-
-
Notifications
You must be signed in to change notification settings - Fork 52.6k
Description
Bug Description
When using reasoning models (e.g. MiniMax M2.5) via OpenRouter with a non-undefined thinking level, OpenClaw sends both reasoning_effort (top-level, OpenAI flat format) and reasoning: { effort } (nested, OpenRouter format) in the API payload. OpenRouter rejects this with:
400 Only one of "reasoning" and "reasoning_effort" may be provided
Root Cause
Two code paths inject reasoning parameters independently:
- pi-ai's
buildParams()inopenai-completions.jssetsparams.reasoning_effort(OpenAI flat format) when a model hasreasoning: trueandcompat.supportsReasoningEffort - OpenClaw's
createOpenRouterWrapper()insrc/agents/pi-embedded-runner/extra-params.tsinjectspayload.reasoning = { effort }(OpenRouter nested format) via theonPayloadhook
The wrapper checks for an existing reasoning object and for max_tokens/effort keys within it, but never removes the conflicting top-level reasoning_effort field that pi-ai already injected.
This was introduced by the interaction between:
- PR fix(openrouter): pass reasoning.effort based on thinking level (#14664) #17236 — added
reasoning.effortinjection to the OpenRouter wrapper - PR Default reasoning to on when model has reasoning: true (fix #22456) #22513 — defaulted reasoning to
onfor models withreasoning: true
Neither PR alone causes the issue, but together they produce the duplicate field.
Steps to Reproduce
- Configure a model via OpenRouter with
reasoning: true(e.g.,minimax/minimax-m2.5) - Set
thinkingDefaultto any value (e.g.,"low") - Send a message
Expected Behavior
Only reasoning: { effort: "<level>" } should be sent to OpenRouter (their expected nested format).
Actual Behavior
Both reasoning_effort: "<level>" (top-level) and reasoning: { effort: "<level>" } (nested) are sent, resulting in a 400 error from OpenRouter.
Environment
- OpenClaw version: 2026.2.22
- Provider: OpenRouter
- Model: minimax/minimax-m2.5 (also affects any reasoning model via OpenRouter)