Skip to content

[Bug]: OpenRouter/Qwen3 stream parsing fails — reasoning_details field not handled, causes payloads=0 #66833

@bickers76

Description

@bickers76

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

Summary

When using openrouter/qwen/qwen3-235b-a22b (or any Qwen3 model via OpenRouter),
every response fails with:

incomplete turn detected: runId=... stopReason=stop payloads=0 — surfacing error to user

The agent shows "⚠️ Agent couldn't generate a response. Please try again."

Root Cause (community-diagnosed in Discord)

src/agents/openai-transport-stream.ts handles these reasoning fields on streamed choice.delta:

  • reasoning_content
  • reasoning
  • reasoning_text

But not reasoning_details — which Qwen3 returns via OpenRouter.

The OpenRouter hook path (createOpenRouterWrapper) is request-side wrapping only — no response normalisation. So reasoning_details passes through unhandled, leaving OpenClaw with no assistant payload blocks, which hits the payloads=0 incomplete-turn path in src/agents/pi-embedded-runner/run.ts.

What was tried (none worked)

  • thinkingDefault: "off" — only stops injecting reasoning effort, does not send OpenRouter exclude: true
  • tools.allow: [] — no tools
  • providerOptions.openrouter.extra_body.enable_thinking: false
  • providerOptions.openrouter.extra_body.thinking: { type: "disabled" }
  • Model variants: qwen3-235b-a22b, qwen3-235b-a22b-2507, qwen3-32b

Direct OpenRouter API call with the same model works correctly — returns content + reasoning_details.

Verification

Raw OpenRouter response includes:

"reasoning_details": [
  {
    "type": "reasoning.text",
    "text": "...",
    "format": "unknown",
    "index": 0
  }
]
This field is not handled in the stream parser, causing zero content blocks to be assembled.

Expected Fix

Handle choice.delta.reasoning_details in openai-transport-stream.ts the same way reasoning_content is handled — extract text content and treat as reasoning tokens, not as a blocking field.

Alternatively, on the OpenRouter response path, strip or ignore unknown reasoning fields so payloads=0 is not triggered when the model returns only reasoning with no text delta.

Workaround

None available in 2026.4.14 without a litellm proxy to strip reasoning_details before OpenClaw parses the stream.


### Steps to reproduce

## Steps to Reproduce

1. Create an agent with `model: "openrouter/qwen/qwen3-235b-a22b"`
2. Send any message to the agent
3. Observe `incomplete turn detected: payloads=0` in gateway logs
4. User receives "⚠️ Agent couldn't generate a response"


### Expected behavior

When a model returns `reasoning_details` in the stream, OpenClaw should treat it the same as other recognised reasoning fields (`reasoning_content`, `reasoning`, `reasoning_text`) — extract the text content and continue assembling the response. The assistant turn should complete successfully with the model's reply visible to the user.


### Actual behavior

When a Qwen3 model responds via OpenRouter, the stream includes a `reasoning_details` field that OpenClaw does not recognise. Because no content blocks are assembled from the unhandled field, the turn completes with `payloads=0`. The agent fails silently and the user sees "⚠️ Agent couldn't generate a response. Please try again."


### OpenClaw version

OpenClaw: 2026.4.14 (323493f)

### Operating system

OS: macOS arm64 (Darwin 25.3.0)

### Install method

npm (stable)

### Model

Model: openrouter/qwen/qwen3-235b-a22b

### Provider / routing chain

Provider: OpenRouter

### Additional provider/model setup details

_No response_

### Logs, screenshots, and evidence

```shell

Impact and severity

No response

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingbug:behaviorIncorrect behavior without a crash

    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