claude-sonnet-5 (Messages API, adaptive thinking high + tools): degenerate no-op bash loop instead of emitting long freeform output
Model: claude-sonnet-5 via the Messages API (direct Anthropic). Also reproduced via OpenRouter (anthropic/claude-sonnet-5) with a milder presentation. Filed here for lack of a public model-behavior tracker; this is a model/API behavior report from a third-party agentic app, not a Claude Code CLI bug, though the config is one Claude-Code-like harnesses commonly use.
Summary
With adaptive thinking at high effort plus a tool loop, claude-sonnet-5 can enter a degenerate loop where it never produces its main deliverable (a large freeform text block) and instead emits an endless sequence of one-sentence commitments followed by no-op bash tool calls. Left alone, a single user turn burned 2.05M input tokens (history re-sent every tool cycle) with zero useful output before the user stopped it.
Setup
- Request config:
thinking: {"type": "adaptive", "display": "summarized"},output_config: {"effort": "high"},max_tokens: 128000. - Tools available:
bash, file tools, and app-specific tools (standard agentic loop; tool results fed back as history each cycle). - Task shape: the system prompt instructs the model to emit a large domain-specific text block (a design DSL, typically 50-200 lines) directly in its assistant text, explicitly stating that no creation tool exists and the block must be written inline.
Observed behavior (direct Anthropic, effort high)
Each cycle, the model:
- Plans extensively in (summarized) thinking — including visibly drafting the exact text block it should emit ("Building the table structure... Adding the price and volume input fields...");
- Streams one sentence of commitment text ("Now let's make the edits.");
- Calls
bashwith a no-op likeecho ok,echo start,echo "canvasId=<id> confirmed"— self-invented "checkpoints" that verify nothing; - Receives the trivial tool result and repeats from step 1.
Two independent sessions ran 20-30 such cycles (604K and 2.05M input tokens respectively, ~15-17K output) with zero emission of the required block, until manually stopped. The thinking text shows the model repeatedly convincing itself it has "confirmed" prerequisites it already had (the target id is present verbatim in its context).
Contrast points
- Same model via OpenRouter (which maps thinking to an explicit
reasoning.max_tokens: 16384budget rather than adaptive effort): the same procrastination pattern appears but the model escapes after 1-4 echo cycles and emits the block. - Older models (e.g.
claude-opus-4-8) in the identical harness/prompt do not exhibit the loop. - The behavior reads like an interaction between adaptive-thinking-high and strong tool-use priors: the model appears to treat "emit a large freeform text artifact" as requiring a tool action, and substitutes a placeholder tool call each cycle.
Impact
For BYOK agentic apps this is a direct cost bug on the user's own API key: the loop is quiet (each cycle looks like normal activity) and only an app-side degenerate-turn guard or the user noticing stops it. We've since shipped a client-side guard (detect consecutive no-op tool batches, inject a corrective nudge, then abort), which works — but the model-side behavior seems worth a look, since any harness exposing bash + a "write your output inline" instruction is susceptible.
Happy to provide additional request-level detail (exact system prompt structure, full request config) privately if useful.