Repository navigation
moonshot AI kimi k2 all get error. #6056
Description
Activity
github-actions commented
on Dec 23, 2025 on Dec 23, 2025 – with GitHub ActionsContributorMore actionsThis issue might be a duplicate of existing issues. Please check:
- Groq Kimi K2 Caching #2174: Groq Kimi K2 Caching - caching-related issues with Kimi K2
- Kimi K2 cache not working on Zen #3172: Kimi K2 cache not working on Zen - similar caching problems with Kimi K2
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.
Can you share a session?
opencode export > session.jsonIt is working now..
and I can see GLM 4.7 on the model list just now.
Maybe something happened during models updating..
Thanks.
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:/** * 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. */ export const FixEmptyAssistantMessages = async () => { const originalFetch = globalThis.fetch; globalThis.fetch = async (url, options) => { const urlStr = typeof url === 'string' ? url : url.toString(); if (urlStr.includes('openrouter') && options?.body) { try { const body = JSON.parse(options.body); if (body.messages) { const before = body.messages.length; body.messages = body.messages.filter(msg => { // Only remove empty assistant messages WITHOUT tool_calls if (msg.role !== 'assistant') return true; const content = msg.content; const hasToolCalls = msg.tool_calls?.length > 0; const isEmpty = !content || (typeof content === 'string' && content.trim() === '') || (Array.isArray(content) && content.length === 0); // Keep if has tool_calls, remove only if truly empty/orphaned return !(isEmpty && !hasToolCalls); }); if (body.messages.length !== before) { options = { ...options, body: JSON.stringify(body) }; } } } catch (e) {} } return originalFetch(url, options); }; return {}; };
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:
so it would probably be better to fix this in the code ultimately, but at least this seems to work for now.
Reacted by Lucas Yang, Nikita Abaturov, yemao688 and Dennis Paul- added a commit that references this issue
on Mar 31, 2026 - added a commit that references this issue
on Jul 23, 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.
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?我非常疑惑,请求帮助,谢谢大家
我把这个信息留在这里,以防其他人遇到同样的错误,因为搜索这个错误时,这似乎是搜索结果中排名第一/唯一的结果……
如果您取消工具调用,有时可能会出现空白的助手消息,这会导致提供商出现类似这样的错误
Moonshot AI,openrouter例如:{
"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
}
}
}
注意: 要找到实际错误,您必须查看日志文件,因为在 TUI 中您只会看到一个神秘的红色“提供商错误”或类似错误!我无法使用常规的
opencode插件钩子来捕获和修复这个问题,但我设法通过以下方式进行了临时修补:/**
- 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:
-
- 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.
-
- 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.
*/
export const FixEmptyAssistantMessages = async () => {
const originalFetch = globalThis.fetch;globalThis.fetch = async (url, options) => {
const urlStr = typeof url === 'string' ? url : url.toString();if (urlStr.includes('openrouter') && options?.body) { try { const body = JSON.parse(options.body); if (body.messages) { const before = body.messages.length; body.messages = body.messages.filter(msg => { // Only remove empty assistant messages WITHOUT tool_calls if (msg.role !== 'assistant') return true; const content = msg.content; const hasToolCalls = msg.tool_calls?.length > 0; const isEmpty = !content || (typeof content === 'string' && content.trim() === '') || (Array.isArray(content) && content.length === 0); // Keep if has tool_calls, remove only if truly empty/orphaned return !(isEmpty && !hasToolCalls); }); if (body.messages.length !== before) { options = { ...options, body: JSON.stringify(body) }; } } } catch (e) {} } return originalFetch(url, options);};
return {};
};
使用方法很简单,只需复制到~/.config/opencode/plugins.官方 API 可能也存在这个问题,
Moonshot因此值得扩大urlStr.includes('openrouter')测试范围。还有很多其他供应商也遇到了类似的问题:
所以最终最好还是在代码中修复这个问题,但至少目前看来这样可以解决问题。
来自提供商的错误(Console Go):上游请求失败:[invalid_request_error] 无效请求:位置 75 处角色为“assistant”的消息不得为空,看到介绍说:“使用方法很简单,只需复制到~/.config/opencode/plugins。”,我现在系统是windows打开目录:“~/.config/opencode/”目录下并没有plugins目录,所以我手动创建了一个插件,但是代码应该以什么文件格式存储?json还是js或者ts?我非常疑惑,请求帮助,大家谢谢
Description
Hello.
Moonshot AI can not be used for now.
Invalid request: the message at position 5 with role 'assistant' must not be emptyall Kimi K2 models shows same error.
OpenCode version
1.0.193
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response