openclaw - 💡(How to fix) Fix `opencode-go/kimi-k2.6` (and other openai-completions models): `reasoning` field leaks through passthrough replay policy, rejected as "Extra inputs are not permitted" on multi-turn

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

OpenClaw's opencode-go provider plugin replays the reasoning field on assistant messages back to openai-completions models that reject unknown fields. Multi-turn tool-using runs against opencode-go/kimi-k2.6 fail on the second turn with:

400 Error from provider: 9 request validation errors:
Extra inputs are not permitted, field: 'messages[15].reasoning',
value: 'The user is sending another bootstrap request. I already completed...'

This is distinct from #70392 / #71491 (which are about reasoning_content — with underscore — being required but missing on Moonshot's direct API). Here the issue is the wrong field name (reasoning — no underscore) being present and rejected via the opencode-go proxy path. The two paths use different replay hooks.

Error Message

400 Error from provider: 9 request validation errors: No thinking → no reasoning field in history → no replay → no error.

Root Cause

Root cause (from dist/ inspection)

Fix Action

Workaround

The 2026.5.12 LLM idle watchdog (#76877) catches the failure and rotates to a configured fallback model, so tasks complete. Cost is ~13s per multi-turn call on the affected primary, plus misleading model fallback decision log entries with fallbackStepFromFailureReason: model_not_found (the model exists; the request body is invalid).

Code Example

400 Error from provider: 9 request validation errors:
Extra inputs are not permitted, field: 'messages[15].reasoning',
value: 'The user is sending another bootstrap request. I already completed...'

---

openclaw agent --agent coder --local --json --message \
  'In your sandbox at /workspace, create probe/hello.txt with contents "READY". Use the Write tool. Reply with exactly: DONE.'

---

...PASSTHROUGH_GEMINI_REPLAY_HOOKS,

---

function buildPassthroughGeminiSanitizingReplayPolicy(modelId) {
  return {
    applyAssistantFirstOrderingFix: false,
    validateGeminiTurns: false,
    validateAnthropicTurns: false,
    ...normalizeLowercaseStringOrEmpty(modelId).includes("gemini") ? {
      sanitizeThoughtSignatures: { ... }
    } : {}
  };
  // No dropReasoningFromHistory
}
RAW_BUFFERClick to expand / collapse

Summary

OpenClaw's opencode-go provider plugin replays the reasoning field on assistant messages back to openai-completions models that reject unknown fields. Multi-turn tool-using runs against opencode-go/kimi-k2.6 fail on the second turn with:

400 Error from provider: 9 request validation errors:
Extra inputs are not permitted, field: 'messages[15].reasoning',
value: 'The user is sending another bootstrap request. I already completed...'

This is distinct from #70392 / #71491 (which are about reasoning_content — with underscore — being required but missing on Moonshot's direct API). Here the issue is the wrong field name (reasoning — no underscore) being present and rejected via the opencode-go proxy path. The two paths use different replay hooks.

Environment

  • OpenClaw 2026.5.12 (commit f066dd2), installed via npm install -g
  • Provider plugin: opencode-go (proxies Moonshot's openai-completions API)
  • Model: opencode-go/kimi-k2.6, thinkingDefault: medium
  • Agent has Docker sandbox (sandbox.mode: all) and exercises tool calls

Reproduction

Configure a coder agent with model.primary: opencode-go/kimi-k2.6, thinkingDefault: medium, then run a two-turn task:

openclaw agent --agent coder --local --json --message \
  'In your sandbox at /workspace, create probe/hello.txt with contents "READY". Use the Write tool. Reply with exactly: DONE.'

The agent issues a Write tool call (turn 1, model produces thinking), receives the tool result, then attempts to generate the final assistant text (turn 2). The turn-2 request replays turn 1's history including the assistant thinking. The provider rejects with the 400 quoted above; the watchdog falls back to a different model and the task completes via the fallback.

Single-turn probes against the same primary (Reply with exactly: PONG, no tool call) succeed first try — the bug only manifests when an assistant turn with thinking is replayed.

Root cause (from dist/ inspection)

/usr/lib/node_modules/openclaw/dist/extensions/opencode-go/index.js (line ~86) installs PASSTHROUGH_GEMINI_REPLAY_HOOKS:

...PASSTHROUGH_GEMINI_REPLAY_HOOKS,

That builder is buildPassthroughGeminiSanitizingReplayPolicy in /usr/lib/node_modules/openclaw/dist/provider-model-shared-D-slKnZa.js (lines 109–119):

function buildPassthroughGeminiSanitizingReplayPolicy(modelId) {
  return {
    applyAssistantFirstOrderingFix: false,
    validateGeminiTurns: false,
    validateAnthropicTurns: false,
    ...normalizeLowercaseStringOrEmpty(modelId).includes("gemini") ? {
      sanitizeThoughtSignatures: { ... }
    } : {}
  };
  // No dropReasoningFromHistory
}

Compare to the unowned-provider fallback buildUnownedProviderTransportReplayFallback in dist/tool-result-middleware-ecm3p4oK.js, which does set dropReasoningFromHistory: true when modelApi === "openai-completions". The passthrough policy used by opencode-go does not, creating an asymmetry: explicit-plugin providers proxying openai-completions models inherit the "leak reasoning on replay" behavior; identical models behind the unowned-fallback path get them stripped.

Per OpenClaw's stored representation, the assistant thinking is { "type": "thinking", "thinking": "...", "thinkingSignature": "reasoning" }. On replay, the thinkingSignature: "reasoning" is serialized to a top-level reasoning field on the outgoing assistant message, which the openai-completions endpoint validates and rejects as an unknown field.

Why single-turn doesn't repro

No thinking → no reasoning field in history → no replay → no error.

Suggested fix

One-line change in buildPassthroughGeminiSanitizingReplayPolicy to include dropReasoningFromHistory: true when the underlying model's API is openai-completions. Pattern is already established in buildUnownedProviderTransportReplayFallback. This keeps Gemini-specific signature sanitization intact while preventing the reasoning leak on openai-completions paths.

Workaround

The 2026.5.12 LLM idle watchdog (#76877) catches the failure and rotates to a configured fallback model, so tasks complete. Cost is ~13s per multi-turn call on the affected primary, plus misleading model fallback decision log entries with fallbackStepFromFailureReason: model_not_found (the model exists; the request body is invalid).

Cross-references

  • #70392 (closed) and #71491 (open) — adjacent bugs about reasoning_content (underscore) being required-but-missing on Moonshot's direct API. Different code path: those used OPENAI_COMPATIBLE_REPLAY_HOOKS for the direct Moonshot provider. The fix that closed #70392 doesn't apply here because opencode-go uses a different replay-hooks set.
  • #78867 (open, github-copilot/gpt-5.5 encrypted_content rejected on replay) — same shape, different model, different field. May share a deeper "history replay sanitization should be capability-aware" theme.
  • #80452 (open, OpenAI Responses missing reasoning item on cross-provider failover from Gemini) — opposite direction (missing-required vs. extra-not-permitted), same family.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix `opencode-go/kimi-k2.6` (and other openai-completions models): `reasoning` field leaks through passthrough replay policy, rejected as "Extra inputs are not permitted" on multi-turn