Skip to content

[Bug] Moonshot K2.6 multi-turn tool calls fail: reasoning_content stripped during replay #70392

@RoseKongPS

Description

@RoseKongPS

Problem

When using moonshot/kimi-k2.6 (or any Moonshot thinking model) with multi-turn tool calls, the second tool-call turn always fails with:

400 Bad Request: thinking is enabled but reasoning_content is missing in assistant tool call message at index N

Root Cause

K2.6 is a thinking model. When it generates a tool call, the Moonshot API returns reasoning_content alongside the standard content and tool_calls fields. The API is stateless and requires clients to echo back the exact reasoning_content when sending the next turn with the tool result.

OpenClaw strips the reasoning_content field during conversation replay. The OPENAI_COMPATIBLE_REPLAY_HOOKS used by the Moonshot provider only handle sanitizeToolCallIds and applyAssistantFirstOrderingFix — it does not preserve reasoning_content on assistant messages.

While pi-ai's convertMessages() does convert thinking blocks back to reasoning_content via thinkingSignature, this only works if the thinking blocks survive through the replay/sanitize pipeline. For Moonshot models, they appear to be lost before reaching convertMessages().

Steps to Reproduce

  1. Configure OpenClaw with moonshot/kimi-k2.6 as primary or fallback model
  2. Start a session and send a message that triggers a tool call
  3. The tool call succeeds (first turn, no replay needed)
  4. Send another message that triggers a second tool call
  5. 400 error: reasoning_content is missing in assistant tool call message

This affects ANY session type (main or subagent). It is not related to history length.

Environment

  • OpenClaw: 2026.4.21 (f788c88)
  • Model: moonshot/kimi-k2.6
  • Provider: Moonshot AI (direct, not OpenRouter)
  • Auth: moonshot:default profile

Expected Behavior

The reasoning_content field from Moonshot assistant messages should be preserved during replay and sent back to the API on subsequent turns.

Workaround

Disable thinking mode by sending {"thinking": {"type": "disabled"}} in the request. This makes K2.6 behave as a standard non-thinking model and bypasses the reasoning_content requirement entirely.

Note: OpenClaw currently does not expose a per-model config option to pass this parameter. Previous attempts to set thinking, thinkingLevel, or params.thinking in agents.defaults.models were rejected as unrecognized keys.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions