openclaw - 💡(How to fix) Fix DeepSeek V4: isSignedThinkingBlock misses unsigned thinking blocks — reasoning-only retry fails

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…

When DeepSeek V4 produces thinking tokens but no visible text (a "reasoning-only" turn), Gateway's reasoning-only retry with "visible-answer continuation" fails to trigger. Instead, the turn hits llm-idle-timeout and falls through to a blind retry that doesn't carry the "continue from partial turn" instruction, which is ineffective for recovering visible output.

Error Message

Not the same as #75040 (which is about extra_body field collision WARN noise).

Root Cause

The detection chain relies on isSignedThinkingBlock(), which requires specific signature fields on the thinking block:

function isSignedThinkingBlock(block) {
  if (!isThinkingBlock(block)) return false;
  return block.type === "redacted_thinking"
    || block.signature != null
    || block.thinkingSignature != null
    || block.thought_signature != null;
}

assessLastAssistantMessage() then uses isSignedThinkingBlock to classify the turn:

  • hasSignedThinking && !hasNonThinkingContent"incomplete-text" ✅ triggers retry
  • hasUnsignedThinking"incomplete-thinking" ❌ not caught by isReasoningOnlyAssistantTurn
function isReasoningOnlyAssistantTurn(message) {
  return assessLastAssistantMessage(message) === "incomplete-text";
}

If DeepSeek V4 APIs return thinking blocks without signature, thinkingSignature, or thought_signature fields, the block is classified as "unsigned thinking". The turn gets "incomplete-thinking" — which is not matched by isReasoningOnlyAssistantTurn, so resolveReasoningOnlyRetryInstruction returns null and no continuation retry is attempted.

Instead, the run hits the default llm-idle-timeout (120s) and retries via sameModelIdleTimeoutRetry, which retries the same model but without the REASONING_ONLY_RETRY_INSTRUCTION ("Continue from that partial turn and produce the visible answer now...") — so the model restarts from scratch and may produce only thinking tokens again.

Code Example

function isSignedThinkingBlock(block) {
  if (!isThinkingBlock(block)) return false;
  return block.type === "redacted_thinking"
    || block.signature != null
    || block.thinkingSignature != null
    || block.thought_signature != null;
}

---

function isReasoningOnlyAssistantTurn(message) {
  return assessLastAssistantMessage(message) === "incomplete-text";
}
RAW_BUFFERClick to expand / collapse

Summary

When DeepSeek V4 produces thinking tokens but no visible text (a "reasoning-only" turn), Gateway's reasoning-only retry with "visible-answer continuation" fails to trigger. Instead, the turn hits llm-idle-timeout and falls through to a blind retry that doesn't carry the "continue from partial turn" instruction, which is ineffective for recovering visible output.

Root Cause

The detection chain relies on isSignedThinkingBlock(), which requires specific signature fields on the thinking block:

function isSignedThinkingBlock(block) {
  if (!isThinkingBlock(block)) return false;
  return block.type === "redacted_thinking"
    || block.signature != null
    || block.thinkingSignature != null
    || block.thought_signature != null;
}

assessLastAssistantMessage() then uses isSignedThinkingBlock to classify the turn:

  • hasSignedThinking && !hasNonThinkingContent"incomplete-text" ✅ triggers retry
  • hasUnsignedThinking"incomplete-thinking" ❌ not caught by isReasoningOnlyAssistantTurn
function isReasoningOnlyAssistantTurn(message) {
  return assessLastAssistantMessage(message) === "incomplete-text";
}

If DeepSeek V4 APIs return thinking blocks without signature, thinkingSignature, or thought_signature fields, the block is classified as "unsigned thinking". The turn gets "incomplete-thinking" — which is not matched by isReasoningOnlyAssistantTurn, so resolveReasoningOnlyRetryInstruction returns null and no continuation retry is attempted.

Instead, the run hits the default llm-idle-timeout (120s) and retries via sameModelIdleTimeoutRetry, which retries the same model but without the REASONING_ONLY_RETRY_INSTRUCTION ("Continue from that partial turn and produce the visible answer now...") — so the model restarts from scratch and may produce only thinking tokens again.

Affected Code

  • selection-BmjEdnnA.jsisSignedThinkingBlock(), assessLastAssistantMessage(), isReasoningOnlyAssistantTurn(), resolveReasoningOnlyRetryInstruction()
  • pi-embedded-CJ87lW5R.js — reasoning-only retry loop

Suggested Fix

Either:

  1. Broaden isReasoningOnlyAssistantTurn to also match "incomplete-thinking" when the model is known to produce thinking blocks without signatures (e.g., DeepSeek V4 OpenAI-compatible API).

  2. Or treat unsigned thinking blocks as signed for provider/model combinations where signatures are not expected — so assessLastAssistantMessage returns "incomplete-text" instead of "incomplete-thinking".

Related

Not the same as #75040 (which is about extra_body field collision WARN noise).

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 DeepSeek V4: isSignedThinkingBlock misses unsigned thinking blocks — reasoning-only retry fails