Skip to content

moonshot AI kimi k2 all get error. #6056

Description

@magic-thomas

Description

Hello.

Moonshot AI can not be used for now.

Invalid request: the message at position 5 with role 'assistant' must not be empty

all 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

Activity

  1. github-actions commented on Dec 23, 2025

    @github-actions
    Contributor

    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.

  2. rekram1-node commented on Dec 23, 2025

    @rekram1-node
    Collaborator

    Can you share a session?

    opencode export > session.json

  3. magic-thomas commented on Dec 24, 2025

    @magic-thomas
    Author

    It is working now..

    and I can see GLM 4.7 on the model list just now.

    Maybe something happened during models updating..

    Thanks.

  4. jukofyork commented on Feb 27, 2026

    @jukofyork

    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.
     */
    
    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 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:

    #2651
    #14586

    so it would probably be better to fix this in the code ultimately, but at least this seems to work for now.

  5. dnnspaul commented on Aug 6, 2026

    @dnnspaul

    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.

  6. fy757056560 commented on Aug 13, 2026

    @fy757056560

    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?我非常疑惑,请求帮助,谢谢大家

  7. fy757056560 commented on Aug 13, 2026

    @fy757056560

    我把这个信息留在这里,以防其他人遇到同样的错误,因为搜索这个错误时,这似乎是搜索结果中排名第一/唯一的结果……

    如果您取消工具调用,有时可能会出现空白的助手消息,这会导致提供商出现类似这样的错误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:
      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.
      1. 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')测试范围。

    还有很多其他供应商也遇到了类似的问题:

    #2651 #14586

    所以最终最好还是在代码中修复这个问题,但至少目前看来这样可以解决问题。

    来自提供商的错误(Console Go):上游请求失败:[invalid_request_error] 无效请求:位置 75 处角色为“assistant”的消息不得为空,看到介绍说:“使用方法很简单,只需复制到~/.config/opencode/plugins。”,我现在系统是windows打开目录:“~/.config/opencode/”目录下并没有plugins目录,所以我手动创建了一个插件,但是代码应该以什么文件格式存储?json还是js或者ts?我非常疑惑,请求帮助,大家谢谢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions