You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The error about empty assistant messages in the conversation history is a known issue affecting Kimi K2 models. Feel free to ignore if none of these address your specific case.
Leaving this here in case anybody else has this same error as it seems to be the top/only hit for this when you search...
If you cancel a tool call you can sometimes end up with a blank/empty assistant message which then causes errors like this for the Moonshot AI provider on openrouter, eg:
{
"responseBody": {
"error": {
"message": "Provider returned error",
"code": 400,
"metadata": {
"raw": {
"error": {
"message": "Invalid request: the message at position XXX with role 'assistant' must not be empty",
"type": "invalid_request_error"
}
},
"provider_name": "Moonshot AI",
"is_byok": false
}
},
"user_id": "user_xxx"
},
"isRetryable": false,
"data": {
"error": {
"message": "Provider returned error",
"code": 400
}
}
}
NOTE:To find the actual error you have to look in the log file as in the TUI you just get a cryptic red "Provider Error" or similar!
I couldn't get the normal opencode plug-in hooks to catch and fix this, but did manage to monkey-patch it like this:
/** * FixEmptyAssistantMessages Plugin * * PROBLEM: * Moonshot AI (and some other providers) reject API calls with empty assistant messages, * returning: "Invalid request: the message at position X with role 'assistant' must not be empty" * * ATTEMPTED SOLUTIONS THAT FAILED: * 1. Plugin hooks (message.updated, message.part.updated, event) - These operate at the * session/database layer, but the empty messages are created AFTER hooks fire and * BEFORE the HTTP request is sent to the provider. The plugin system doesn't expose * the provider transform layer where filtering needs to happen. * * 2. Removing ALL empty assistant messages - This broke tool call chains because * subsequent "tool" role messages reference the tool_call_id from the assistant * messages. Removing them caused "tool_call_id is not found" errors. * * SOLUTION: * Monkey-patch global.fetch to intercept the API request body and filter messages * at the HTTP layer. This is the only layer where we can see the final message array * being sent to the provider. * * KEY INSIGHT: * Empty content (null/undefined/"") is acceptable to Moonshot IF the assistant message * has tool_calls. Only messages with BOTH empty content AND no tool_calls need to be * removed - these are "orphaned" empty messages that serve no purpose. */exportconstFixEmptyAssistantMessages=async()=>{constoriginalFetch=globalThis.fetch;globalThis.fetch=async(url,options)=>{consturlStr=typeofurl==='string' ? url : url.toString();if(urlStr.includes('openrouter')&&options?.body){try{constbody=JSON.parse(options.body);if(body.messages){constbefore=body.messages.length;body.messages=body.messages.filter(msg=>{// Only remove empty assistant messages WITHOUT tool_callsif(msg.role!=='assistant')returntrue;constcontent=msg.content;consthasToolCalls=msg.tool_calls?.length>0;constisEmpty=!content||(typeofcontent==='string'&&content.trim()==='')||(Array.isArray(content)&&content.length===0);// Keep if has tool_calls, remove only if truly empty/orphanedreturn!(isEmpty&&!hasToolCalls);});if(body.messages.length!==before){options={ ...options,body: JSON.stringify(body)};}}}catch(e){}}returnoriginalFetch(url,options);};return{};};
To use just copy to ~/.config/opencode/plugins.
It probably manifests itself for the official Moonshot API too so it might be worth widening the urlStr.includes('openrouter') test.
There are a a lot of other PRs related to this for other providers:
Error from provider (Console Go): Upstream request failed: [invalid_request_error] Invalid request: the message at position 75 with role 'assistant' must not be empty,看到介绍说:"使用方法很简单,只需复制到~/.config/opencode/plugins.",我现在系统是windows打开目录:"~/.config/opencode/"目录下并没有plugins目录,于是我手动创建了一个plugins,可是代码应该以什么文件格式存储?json还是js或者ts?我非常疑惑,请求帮助,谢谢大家
Activity
github-actions commentedon Dec 23, 2025
This issue might be a duplicate of existing issues. Please check:
The error about empty assistant messages in the conversation history is a known issue affecting Kimi K2 models. Feel free to ignore if none of these address your specific case.
rekram1-node commentedon Dec 23, 2025
Can you share a session?
opencode export > session.jsonmagic-thomas commentedon Dec 24, 2025
It is working now..
and I can see GLM 4.7 on the model list just now.
Maybe something happened during models updating..
Thanks.
jukofyork commentedon Feb 27, 2026
Leaving this here in case anybody else has this same error as it seems to be the top/only hit for this when you search...
If you cancel a tool call you can sometimes end up with a blank/empty assistant message which then causes errors like this for the
Moonshot AIprovider onopenrouter, eg:{ "responseBody": { "error": { "message": "Provider returned error", "code": 400, "metadata": { "raw": { "error": { "message": "Invalid request: the message at position XXX with role 'assistant' must not be empty", "type": "invalid_request_error" } }, "provider_name": "Moonshot AI", "is_byok": false } }, "user_id": "user_xxx" }, "isRetryable": false, "data": { "error": { "message": "Provider returned error", "code": 400 } } }NOTE: To find the actual error you have to look in the log file as in the TUI you just get a cryptic red "Provider Error" or similar!
I couldn't get the normal
opencodeplug-in hooks to catch and fix this, but did manage to monkey-patch it like this:To use just copy to
~/.config/opencode/plugins.It probably manifests itself for the official
MoonshotAPI too so it might be worth widening theurlStr.includes('openrouter')test.There are a a lot of other PRs related to this for other providers:
#2651
#14586
so it would probably be better to fix this in the code ultimately, but at least this seems to work for now.
fix: filter empty assistant messages for all providers
fix: filter empty assistant messages to prevent provider errors (issu…
dnnspaul commentedon Aug 6, 2026
Have the same problem with kimi-k3 now from time to time. We use it through requesty and it often happens within subagent-tasks.
Trying out @jukofyork monkey-patch now.
fy757056560 commentedon Aug 13, 2026
Error from provider (Console Go): Upstream request failed: [invalid_request_error] Invalid request: the message at position 75 with role 'assistant' must not be empty,看到介绍说:"使用方法很简单,只需复制到~/.config/opencode/plugins.",我现在系统是windows打开目录:"~/.config/opencode/"目录下并没有plugins目录,于是我手动创建了一个plugins,可是代码应该以什么文件格式存储?json还是js或者ts?我非常疑惑,请求帮助,谢谢大家
fy757056560 commentedon Aug 13, 2026
来自提供商的错误(Console Go):上游请求失败:[invalid_request_error] 无效请求:位置 75 处角色为“assistant”的消息不得为空,看到介绍说:“使用方法很简单,只需复制到~/.config/opencode/plugins。”,我现在系统是windows打开目录:“~/.config/opencode/”目录下并没有plugins目录,所以我手动创建了一个插件,但是代码应该以什么文件格式存储?json还是js或者ts?我非常疑惑,请求帮助,大家谢谢