错误信息: The role only supports :`user`、`assistant` - `messages.[0]` 堆栈信息: AI_APICa...

2026年01月26日 21:35 状态: processing

🚨 错误信息

错误名称: AI_APICallError 错误信息: The role only supports :`user`、`assistant` - `messages.[0]` 堆栈信息: AI_APICallError: The role only supports :`user`、`assistant` - `messages.[0]` at file:///C:/Users/karl_/AppData/Local/Programs/Cherry%20Studio/resources/app.asar/out/renderer/assets/dist-CtZQEYA8.js:346:11 at async postToApi (file:///C:/Users/karl_/AppData/Local/Programs/Cherry%20Studio/resources/app.asar/out/renderer/assets/dist-CtZQEYA8.js:279:24) at async OpenAICompatibleChatLanguageModel.doStream (file:///C:/Users/karl_/AppData/Local/Programs/Cherry%20Studio/resources/app.asar/out/renderer/assets/dist-CtZQEYA8.js:769:48) at async wrapStream (file:///C:/Users/karl_/AppData/Local/Programs/Cherry%20Studio/resources/app.asar/out/renderer/assets/store-BH4SMZS1.js:38051:32) at async fn (file:///C:/Users/karl_/AppData/Local/Programs/Cherry%20Studio/resources/app.asar/out/renderer/assets/store-BH4SMZS1.js:36242:17) at async file:///C:/Users/karl_/AppData/Local/Programs/Cherry%20Studio/resources/app.asar/out/renderer/assets/store-BH4SMZS1.js:33659:19 at async _retryWithExponentialBackoff (file:///C:/Users/karl_/AppData/Local/Programs/Cherry%20Studio/resources/app.asar/out/renderer/assets/store-BH4SMZS1.js:33761:10) at async streamStep (file:///C:/Users/karl_/AppData/Local/Programs/Cherry%20Studio/resources/app.asar/out/renderer/assets/store-BH4SMZS1.js:36210:108) at async fn (file:///C:/Users/karl_/AppData/Local/Programs/Cherry%20Studio/resources/app.asar/out/renderer/assets/store-BH4SMZS1.js:36489:5) at async file:///C:/Users/karl_/AppData/Local/Programs/Cherry%20Studio/resources/app.asar/out/renderer/assets/store-BH4SMZS1.js:33659:19 错误原因: "[undefined]" 状态码: 400 请求路径: https://www.dmxapi.cn/v1/chat/completions 请求体: { "model": "Baichuan-M3-Plus", "user": "[undefined]", "max_tokens": "[undefined]", "temperature": 1, "top_p": "[undefined]", "frequency_penalty": "[undefined]", "presence_penalty": "[undefined]", "response_format": "[undefined]", "stop": "[undefined]", "seed": "[undefined]", "serviceTier": "[undefined]", "reasoning_effort": "[undefined]", "verbosity": "[undefined]", "messages": [ { "role": "system", "content": "\n## Hub MCP Tools – Code Execution Mode\n\nYou can discover and call MCP tools through the hub server using **ONLY two meta-tools**: **search** and **exec**.\n\n### ⚠️ IMPORTANT: You can ONLY call these two tools directly\n\n| Tool | Purpose |\n|------|---------|\n| `search` | Discover available tools and their signatures |\n| `exec` | Execute JavaScript code that calls the discovered tools |\n\n**All other tools (listed in \"Discoverable Tools\" below) can ONLY be called from INSIDE `exec` code.**\nYou CANNOT call them directly as tool calls. They are async functions available within the `exec` runtime.\n\n### Critical Rules (Read First)\n\n1. **ONLY `search` and `exec` are callable as tools.** All other tools must be used inside `exec` code.\n2. You MUST explicitly `return` the final value from your `exec` code. If you do not return a value, the result will be `undefined`.\n3. All MCP tools inside `exec` are async functions. Always call them as `await ToolName(params)`.\n4. Use the exact function names and parameter shapes returned by `search`.\n5. You CANNOT call `search` or `exec` from inside `exec` code—use them only as direct tool calls.\n6. `console.log` output is NOT the result. Logs are separate; the final answer must come from `return`.\n\n### Workflow\n\n1. Call `search` with relevant keywords to discover tools.\n2. Read the returned JavaScript function declarations and JSDoc to understand names and parameters.\n3. Call `exec` with JavaScript code that uses the discovered tools and ends with an explicit `return`.\n4. Use the `exec` result as your answer.\n\n### What `search` Does\n\n- Input: keyword string (comma-separated for OR-matching), plus optional `limit`.\n- Output: JavaScript async function declarations with JSDoc showing exact function names, parameters, and return types.\n\n### What `exec` Does\n\n- Runs JavaScript code in an isolated async context (wrapped as `(async () => { your code })())`.\n- All discovered tools are exposed as async functions: `await ToolName(params)`.\n- Available helpers:\n - `parallel(...promises)` → `Promise.all(promises)`\n - `settle(...promises)` → `Promise.allSettled(promises)`\n - `console.log/info/warn/error/debug`\n- Returns JSON with: `result` (your returned value), `logs` (optional), `error` (optional), `isError` (optional).\n\n### Example: Single Tool Call\n\n```javascript\n// Step 1: search({ query: \"browser,fetch\" })\n// Step 2: exec with:\nconst page = await CherryBrowser_fetch({ url: \"https://example.com\" })\nreturn page\n```\n\n### Example: Multiple Tools with Parallel\n\n```javascript\nconst [forecast, time] = await parallel(\n Weather_getForecast({ city: \"Paris\" }),\n Time_getLocalTime({ city: \"Paris\" })\n)\nreturn { city: \"Paris\", forecast, time }\n```\n\n### Example: Handle Partial Failures with Settle\n\n```javascript\nconst results = await settle(\n Weather_getForecast({ city: \"Paris\" }),\n Weather_getForecast({ city: \"Tokyo\" })\n)\nconst successful = results.filter(r => r.status === \"fulfilled\").map(r => r.value)\nreturn { results, successful }\n```\n\n### Example: Error Handling\n\n```javascript\ntry {\n const user = await User_lookup({ email: \"user@example.com\" })\n return { found: true, user }\n} catch (error) {\n return { found: false, error: String(error) }\n}\n```\n\n### Common Mistakes to Avoid\n\n❌ **Forgetting to return** (result will be `undefined`):\n```javascript\nconst data = await SomeTool({ id: \"123\" })\n// Missing return!\n```\n\n✅ **Always return**:\n```javascript\nconst data = await SomeTool({ id: \"123\" })\nreturn data\n```\n\n❌ **Only logging, not returning**:\n```javascript\nconst data = await SomeTool({ id: \"123\" })\nconsole.log(data) // Logs are NOT the result!\n```\n\n❌ **Missing await**:\n```javascript\nconst data = SomeTool({ id: \"123\" }) // Returns Promise, not value!\nreturn data\n```\n\n❌ **Awaiting before parallel**:\n```javascript\nawait parallel(await ToolA(), await ToolB()) // Wrong: runs sequentially\n```\n\n✅ **Pass promises directly to parallel**:\n```javascript\nawait parallel(ToolA(), ToolB()) // Correct: runs in parallel\n```\n\n### Best Practices\n\n- Always call `search` first to discover tools and confirm signatures.\n- Always use an explicit `return` at the end of `exec` code.\n- Use `parallel` for independent operations that can run at the same time.\n- Use `settle` when some calls may fail but you still want partial results.\n- Prefer a single `exec` call for multi-step flows.\n- Treat `console.*` as debugging only, never as the primary result.\n\n## Discoverable Tools (ONLY usable inside `exec` code, NOT as direct tool calls)\n\nThe following tools are available inside `exec`. Use `search` to get their full signatures.\nDo NOT call these directly—wrap them in `exec` code.\n\n- CherryBrowser_open: Navigate to a URL in a browser window. If format i...\n- CherryBrowser_execute: Run JavaScript in the currently open page. Use aft...\n- CherryBrowser_reset: Close browser windows and clear state. Call when d...\n- CherryFetch_fetchHtml: Fetch a website and return the content as HTML\n- CherryFetch_fetchMarkdown: Fetch a website and return the content as Markdown\n- CherryFetch_fetchTxt: Fetch a website, return the content as plain text ...\n- CherryFetch_fetchJson: Fetch a JSON file from a URL\n" }, { "role": "user", "content": "\n请以专业皮肤科医生的角度,为患有湿疹的成年人提供一套科学、实用的日常护理方案。重点说明如何在**保湿**和**保持皮肤干爽**之间取得平衡,并指出常见的护理误区。要求回答包含以下三个部分:\n1. **核心原则**:简要解释为什么湿疹护理既要保湿又要防潮;\n2. **具体步骤**:分步骤列出每日护理流程(包括清洁、保湿、衣物选择等);\n3. **常见误区及纠正**:列举至少两个患者常犯的错误,并给出正确做法。\n注意:不要使用医学术语堆砌,要用通俗易懂的语言表达,适合普通大众理解。" } ], "tools": "[undefined]", "tool_choice": "[undefined]", "stream": true, "stream_options": { "include_usage": true } } 响应首部: { "cache-control": "no-cache", "content-type": "text/event-stream", "date": "Mon, 26 Jan 2026 13:34:01 GMT", "document-policy": "include-js-call-stacks-in-crash-reports", "server": "nginx", "x-rixapi-request-id": "2026012621340168101725e1Xc7ih3" } 响应内容: { "error": { "message": "The role only supports :`user`、`assistant` - `messages.[0]`", "type": "rix_api_error", "param": "", "code": null } } 数据: { "error": { "message": "The role only supports :`user`、`assistant` - `messages.[0]`", "type": "rix_api_error", "param": "", "code": null } }

🤖 AI解决方案

错误翻译

``
原文:The role only supports :
userassistant - messages.[0]
译文:角色只支持:
userassistant - 消息数组的第一个元素
`

##

根本原因:API请求中的第一条消息(messages[0])使用了不支持的role: "system"。该API仅允许第一条消息的角色为userassistant

具体分析

  • 从请求体可见,messages数组的第一个元素是{ "role": "system", "content": "..." }

  • 错误信息明确指出messages.[0](即第一个消息)的角色限制

  • 这个错误发生在调用Baichuan-M3-Plus模型时,该模型对消息格式有特定要求 解决方案
  • 解决方案1:将system消息合并到user消息中(推荐)

    javascript
    // 修改前的错误代码结构:
    messages: [
    { role: "system", content: "系统指令..." },
    { role: "user", content: "用户问题..." }
    ]

    // 修改后的正确代码结构:
    messages: [
    {
    role: "user",
    content: "系统指令:\n## Hub MCP Tools – Code Execution Mode...\n\n用户问题:请以专业皮肤科医生的角度..."
    }
    ]

    解决方案2:将system消息转换为user消息格式

    javascript
    // 直接修改第一个消息的角色:
    const requestBody = {
    model: "Baichuan-M3-Plus",
    messages: [
    {
    role: "user", // 将"system"改为"user"
    content: "\n## Hub MCP Tools – Code Execution Mode...\n\n请以专业皮肤科医生的角度..."
    }
    ],
    stream: true,
    // ... 其他参数
    }

    ##措施

    ###建议:

  • API兼容性检查:在使用特定模型前,务必查阅其API文档,了解对消息格式的特殊要求。不同的模型可能有不同的消息角色限制。
  • 消息格式验证:在发送请求前,添加验证逻辑检查messages`数组:

  • javascript
    function validateMessages(messages) {
    if (messages.length === 0) return false;
    if (messages[0].role !== 'user' && messages[0].role !== 'assistant') {
    console.error('第一条消息的角色必须是 user 或 assistant');
    return false;
    }
    return true;
    }

    ️ 工具推荐:

  • 使用Postman或类似的API测试工具先进行小规模测试

  • 在代码中添加详细的日志记录,捕获完整的请求体和响应信息,便于调试