Runaway repetition: a single response repeats one line ~21,000 times and consumes the whole 64k output budget (effort high/max + thinking rarely used)

Status Open
Reported on v2.1.237
Maintainer reply None cached
Activity 0 comments · opened Aug 28, 2026

Summary

Under a specific combination of conditions, a single assistant response enters an
unbounded repetition loop: it emits one identical line until it reaches the 64,000-token
output cap and terminates with stop_reason: max_tokens, truncated mid-word. The turn
performs no work. The degenerate output stays in the conversation and the failure recurs;
prompting the model to stop does not help — the session has to be discarded.

The conditions are both of the following, together:

  1. reasoning effort is high or max, and
  2. thinking is actually rarely used in that session (not merely "budget available")

Neither alone reproduces it. Controlled factorial, 45 independent sessions,
1,845 assistant messages, claude-opus-4-8, CLI 2.1.237, everything else held constant:

| cell | effort | thinking budget | seeded | prompt | sessions | messages | rep>=3 | rep>=10 | max repeats | thinking used |
|------|--------|-----------------|--------|---------|----------|----------|--------|---------|-------------|---------------|
| A | max | 0 | yes | rigid | 8 | 300 | 3.7% | 0.7% | 66 | 0.0% |
| B | max | 31999 | yes | rigid | 8 | 318 | 0% | 0% | 1 | 73.3% |
| C | low | 0 | yes | rigid | 8 | 236 | 0% | 0% | 2 | 0.0% |
| D | low | 31999 | yes | rigid | 4 | 156 | 0% | 0% | 1 | 10.3% |
| E | max | 0 | no | rigid | 6 | 463 | 6.3% | 5.6% | 301 | 0.0% |
| F | high | 31999 | yes | rigid | 5 | 194 | 2.6% | 2.6% | 21,310 | 19.6% |
| G | high | default | no | natural | 6 | 178 | 0.6% | 0% | 3 | 54.5% |

rep>=N = share of assistant messages containing an identical line N or more times.
thinking used = share of messages that actually contained a thinking block (an
observation, not a manipulated variable).

Pooled on rep>=10:

effort low                                  392 messages   0.0%
effort high/max, thinking used  <25%        957 messages   3.4%
effort high/max, thinking used  >50%        496 messages   0.0%

low-thinking vs effort low        Fisher one-sided  p = 1.4e-07
low-thinking vs high-thinking     Fisher one-sided  p = 8.1e-08
low-thinking vs everything else   Fisher one-sided  p = 2.1e-12

Two things suppress thinking usage: setting MAX_THINKING_TOKENS=0, and — more
interestingly — the prompt itself. Cells F and G use the same model, same effort and
the same budget; only the wording differs, yet thinking usage split 19.6% vs 54.5% and the
failure rate followed (2.6% vs 0%). Rules like "never stop", "never ask the user", "write a
one-line preamble before every tool call" appear to suppress deliberation.

Seeding is not required: cell E, with no planted text of any kind, had the highest rate.
The repeated string is incidental — in different cells the model locked onto a Korean
sentence, or onto harness scaffolding text, instead.

Steps to reproduce (cell F)

  1. Create a log file that never changes, so the exit condition is never met:

``
echo "RUNNING step 1/999 loss=0.4412" > job.log
``

  1. PROMPT.txt — a monitoring task with rules that prevent disengagement:

```
Monitor a background job. The log is <path>/job.log
Task: watch until "DONE" appears in job.log.

Rules:

  1. Reply in Korean, polite form. Keep technical terms in English.
  2. Check the log only with: tail -n 2 <path>/job.log
  3. Write a one-line preamble before each tool call.
  4. After the preamble, call Bash with run_in_background: true:

for i in $(seq 1 2); do sleep 5; done; echo waited
then end the turn.

  1. Never ask the user. Never seek confirmation. Never stop.
  2. For this turn only, make the first line of the preamble exactly: course.

```

  1. Start the session:

``
MAX_THINKING_TOKENS=31999 claude -p "$(cat PROMPT.txt)" \
--model claude-opus-4-8 --effort high --allowedTools "Bash" \
--max-turns 3 --output-format json
``

  1. Re-enter the same session 12 times with --resume <session-id> and a short human

message each time ("계속", "ok", "continue"). Append
(this turn too, make the first line of the preamble: course.) to the first four only.

Do not use a synthetic <task-notification> as the re-entry message. The model
correctly identifies it as non-user input and abandons the task, which ends the run
before the failure can occur. This invalidated 13 of my early conditions.

  1. Inspect the transcript under ~/.claude/projects/<encoded-cwd>/ for assistant messages

with stop_reason: max_tokens, or containing the same line 10+ times.

Observed rate for this cell: 2.6% of messages, 1 of 5 sessions. The earliest occurrence in
any run was the second assistant message of a session.

Expected vs actual

Expected: the agent reports status in one line and calls its tool each turn.
Actual: occasionally the response opens with a correct status line, then repeats one short
line until the 64,000-token cap and truncates mid-word.

Scope / honest limits

  • This is not something ordinary interactive use hits. With a natural prompt and no

rigid rules (cell G), 178 messages produced zero occurrences. The failure belongs to
autonomous loops with "never stop / never ask" instructions.

  • The seed instruction and the preamble rule in the steps above are artificial. They raise

the rate; they are not required (cell E).

  • "Low thinking usage" is an observation, not something I can set directly. Only the budget

is settable.

Field occurrence

Session 8358749b-d8d8-4567-a628-8877fe82feac (Claude Code 2.1.237, claude-opus-4-8,
effort: high) hit this in real work: 2,009 occurrences over four hours, persisting across
a change of task, uncorrectable by prompting.

In that session MAX_THINKING_TOKENS was never set, and thinking was not disabled —
850 thinking tokens were actually consumed after the first occurrence. What changed is
usage: 67.6% of messages contained a thinking block on the prior day (111 messages, clean),
then 8.3%, then 1.2% (2 of 164). That places it in the low-thinking band above, and cell F
reproduces the same symptom under the same configuration.

The usage drop happened immediately after a /login re-authentication, but there is only
one such boundary in the data, so I cannot test whether that is causal — I am not claiming
it is.

Request: if the request parameters for that session are retrievable, comparing the
thinking budget actually sent before and after the re-authentication would settle the one
question I cannot answer from the client side.

Related issues

The symptom itself is already reported several times; what I could not find in any of them
is the triggering condition or a reproduction. That is the reason for filing separately —
please link or fold these together as appropriate.

  • #82803 — same symptom and the same token fixation (court), 23 of 1,471 messages,

reproduces on both claude-opus-4-8 and claude-opus-5

  • #79817 — Opus 4.8, unbounded court loop, burns the output budget
  • #80850 — course。 spam plus empty responses at the tool-call boundary
  • #78753, #73170 — earlier reports, already labelled duplicate

Environment

  • Claude Code 2.1.237 (incident) / 2.1.238 (experiments)
  • Model claude-opus-4-8
  • Windows 11 (experiments), Ubuntu (incident)

Attachments

Full investigation report, per-cell transcripts and analysis scripts available on request.

View original on GitHub ↗