错误信息: The role only supports :`user`、`assistant` - `messages.[0]` 堆栈信息: AI_APICa...
🚨 错误信息
错误名称: 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解决方案
错误翻译
``user
原文:The role only supports :、assistant - messages.[0]user
译文:角色只支持:、assistant - 消息数组的第一个元素`
##
根本原因:API请求中的第一条消息(messages[0])使用了不支持的role: "system"。该API仅允许第一条消息的角色为user或assistant。
具体分析:
数组的第一个元素是{ "role": "system", "content": "..." }(即第一个消息)的角色限制模型时,该模型对消息格式有特定要求 解决方案解决方案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,
// ... 其他参数
}
##措施
###建议:
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;
}
️ 工具推荐: