CLAUDE LABJP
FORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as OctoberFORK — Claude Code 2.1.212 changes what /fork does: it copies your conversation into a new background session with its own row in claude agents, so you can keep working. The old in-session subagent is now /subtaskLIMITS — WebSearch calls are now capped at 200 per session by default, and subagent spawns get the same 200 ceiling, so a runaway search or delegation loop stops on its ownMCPBG — MCP tool calls running past two minutes now move to the background automatically, keeping the session usable. Tune the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MSPLANFIX — Fixed plan mode auto-running file-modifying Bash commands such as touch and rm without a permission prompt or an SDK canUseTool callbackSONNET5 — Claude Sonnet 5 is running on introductory pricing of $2 per million input tokens and $10 per million output. After August 31 it moves to $3 and $15IPO — Bankers are reportedly lining up investor meetings for Anthropic ahead of a possible public listing as soon as October
Articles/Claude.ai
Claude.ai/2026-04-09Intermediate

Fixing Claude Extended Thinking When It Stops, Times Out, or Loops

Extended Thinking stopping mid-process, hitting timeouts, or consuming unexpected costs? This guide covers root causes, correct budget_tokens configuration, streaming patterns, retry handling, and cost optimization strategies.

Extended Thinking3troubleshooting87timeout9API27optimization4advanced11

Premium Article

Claude's Extended Thinking is one of its most powerful capabilities—when it works. Watching Claude reason through a complex problem step by step, surface hidden assumptions, and arrive at a well-grounded answer is genuinely impressive. But many developers and power users hit a wall early: the thinking stops partway through, a timeout error is returned, or the API bill arrives with numbers that weren't expected.

As an indie developer, I run Extended Thinking in a couple of small apps I maintain on my own—drafting support replies and classifying incoming questions. In the early days, a nightly batch would fail on timeouts about half the time, and opening the morning logs became a small dread. None of the causes were dramatic; every one of them was a minor configuration mistake. What follows is what I checked, hands on keyboard, so that fewer people get stuck in the same places.

This guide takes a systematic look at the most common Extended Thinking failures, explains what's actually happening under the hood, and gives you practical solutions—including working code—to fix each one.

How Extended Thinking Works (and Why It Fails)

Before fixing problems, it helps to understand the mechanism.

When you enable Extended Thinking, Claude generates a thinking block before composing its final answer. Inside this block, Claude explores hypotheses, tests its own reasoning, considers counterarguments, and works toward a conclusion. This thinking content is generated as tokens—which is why the budget_tokens parameter exists. It sets the maximum number of tokens Claude is allowed to spend on thinking before it must produce a final answer.

There are a few key constraints to keep in mind:

Extended Thinking is available on Claude Sonnet 4.6 and Claude Opus 4.6 as of April 2026. Haiku models do not support it. Enabling Extended Thinking significantly increases cost compared to standard generation. The budget_tokens value represents a ceiling, not a guarantee—Claude may use less, but can use up to the limit. And critically, max_tokens must cover both the thinking budget and the final answer.

Troubleshooting by Failure Pattern

Pattern 1: Timeout errors returned from the API

This is the most common Extended Thinking issue. You send a request and receive a timeout or APITimeoutError back.

What's happening Without streaming, your HTTP connection must stay open until the first token is returned. For Extended Thinking requests with a large budget_tokens value, Claude may take a significant amount of time before generating any output—long enough to exceed the default request timeout.

Fix: Use streaming

Streaming keeps the connection alive as tokens are generated, effectively solving timeout issues for the vast majority of cases.

import anthropic
 
client = anthropic.Anthropic()
 
# Streaming approach—timeout-resistant
with client.messages.stream(
    model="claude-sonnet-4-6",
    max_tokens=20000,
    thinking={
        "type": "enabled",
        "budget_tokens": 10000
    },
    messages=[
        {"role": "user", "content": "Your complex question here"}
    ]
) as stream:
    # Stream events as they arrive
    for event in stream:
        pass  # Handle events as needed
 
    # Get the complete final message
    final = stream.get_final_message()
 
    # Extract thinking and answer
    for block in final.content:
        if block.type == "thinking":
            print(f"Thinking: {block.thinking[:200]}...")
        elif block.type == "text":
            print(f"Answer: {block.text}")

Fix: Start with smaller budget_tokens values

If you set budget_tokens to 100,000 for a question that only needs 8,000 tokens of thinking, you're creating unnecessary risk and cost. Start conservative and tune upward.

# Preset budgets by problem complexity
BUDGET_PRESETS = {
    "simple":   5_000,   # Basic math, straightforward logic
    "moderate": 10_000,  # Multi-step reasoning, analysis
    "complex":  20_000,  # Strategic design, complex analysis
    "extreme":  50_000,  # Research-level, philosophical problems
}

Pattern 2: Thinking block is present but the final answer is empty or truncated

Claude completes the thinking phase but returns little or nothing in the actual response text.

What's happening max_tokens is not set high enough. In Extended Thinking mode, max_tokens covers both the thinking tokens and the final answer tokens. If budget_tokens is close to or equal to max_tokens, there may not be enough token headroom left for a proper answer.

Fix: Give max_tokens enough runway

# Problematic configuration
response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=10000,       # 10k total
    thinking={
        "type": "enabled",
        "budget_tokens": 10000  # Thinking can consume ALL of max_tokens!
    },
    ...
)
 
# Correct configuration
response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=22000,       # 15k thinking + 7k for answer
    thinking={
        "type": "enabled",
        "budget_tokens": 15000
    },
    ...
)

Rule of thumb: Set max_tokens to at least budget_tokens + 5000. For detailed technical answers, allow budget_tokens + 10000 to be safe.

Pattern 3: Thinking loops or repeats the same analysis

When you read the thinking block, Claude appears to be going in circles—re-examining the same considerations multiple times without making progress toward an answer.

What's happening Ambiguous or contradictory constraints in your prompt can cause Claude to keep reconsidering its approach without being able to commit to one. This wastes thinking tokens and often produces a weaker final answer.

Fix: Provide structure and clear constraints

# Ambiguous prompt—likely to cause thinking loops
messages = [
    {"role": "user", "content": "Evaluate this business plan."}
]
 
# Structured prompt—gives Claude a clear path forward
messages = [
    {
        "role": "user",
        "content": """
Evaluate the following business plan across three dimensions:
 
1. Market size — assess the claimed TAM with reference to verifiable data
2. Competitive differentiation — compare against the three named competitors
3. Financial feasibility — review the three-year cash flow projections
 
Constraints:
- Keep each dimension to 150-250 words
- Avoid vague language like "may" or "could"—ground claims in evidence
- End with an overall rating from 1 to 5 with a one-sentence rationale
 
Business plan:
{business_plan}
"""
    }
]

Pattern 4: Costs are much higher than expected

Extended Thinking is priced on output tokens, including thinking tokens. Unexpected costs usually mean thinking is consuming more tokens than anticipated.

Monitor your token usage

response = client.messages.create(...)
 
# Count thinking tokens separately
thinking_tokens = 0
answer_tokens = 0
 
for block in response.content:
    if block.type == "thinking":
        # Approximate token count from character length
        thinking_tokens += len(block.thinking) // 4
    elif block.type == "text":
        answer_tokens += len(block.text) // 4
 
total_output = response.usage.output_tokens
print(f"Thinking tokens (approx): {thinking_tokens:,}")
print(f"Answer tokens (approx): {answer_tokens:,}")
print(f"Total output tokens: {total_output:,}")
 
# Rough cost estimate for Sonnet 4.6
cost = (response.usage.input_tokens * 3 + total_output * 15) / 1_000_000
print(f"Estimated cost: ${cost:.4f}")

Cost optimization: Only activate Extended Thinking when you need it

def ask_claude(question: str, complexity: str = "auto") -> str:
    use_thinking = complexity == "high" or (
        complexity == "auto" and _needs_deep_reasoning(question)
    )
 
    kwargs = {
        "model": "claude-sonnet-4-6",
        "max_tokens": 8000,
        "messages": [{"role": "user", "content": question}]
    }
 
    if use_thinking:
        kwargs["thinking"] = {"type": "enabled", "budget_tokens": 10000}
        kwargs["max_tokens"] = 20000
 
    response = client.messages.create(**kwargs)
    return next(b.text for b in response.content if b.type == "text")
 
def _needs_deep_reasoning(question: str) -> bool:
    reasoning_signals = [
        "prove", "optimize", "compare", "design", "why does", "analyze",
        "trade-off", "best approach", "evaluate"
    ]
    return any(signal in question.lower() for signal in reasoning_signals)

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Cause-and-fix coverage with working code for all four common symptoms: timeouts, empty answers, thinking loops, and cost overruns
The production design decisions you actually need: safe max_tokens-to-budget ratios, streaming, and retries with exponential backoff
Real measured thinking-token usage and cost from running this in a small indie app, so you can size budgets with confidence
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Claude.ai2026-05-04
How to Fix the "Tool Result Could Not Be Submitted" Error in Claude
A practical guide to diagnosing and fixing the "tool result could not be submitted" error in Claude's tool use API, based on real development experience.
Claude.ai2026-04-08
Why Does Claude Stop Mid-Response? Fixing Truncation and Garbled Text
If Claude keeps cutting off mid-response or generating garbled text, this guide explains the most common causes — token limits, context windows, network timeouts, and encoding issues — and how to fix each one quickly.
Claude.ai2026-04-04
Claude Not Responding or Freezing — How to Tell the Cause Apart and Fix It
A diagnosis-first guide to Claude not responding or freezing. Learn to split the problem into browser-side and API-side, decide when to wait, reload, or fix your code — with timeout and retry examples included.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →