Opus 5: a transient 529/500 terminates a background subagent mid-unit, and the parent must reconstruct what survived

Status Open
Maintainer reply None cached
Activity 0 comments · opened Jul 30, 2026

Claude Code — a transient 529/500 terminates a background subagent mid-unit, and the parent must notice

Filed: 2026-07-30 · Model: Opus 5 (claude-opus-5, 1M context) · Account: simplysdm
Sessions: d3edf55e-1728-4dc0-b25e-2cbe6853453e (primary), b8ca66e0, eefdc3b5, 5bbc6cf6

Mechanism report, not a complaint about capacity. The interesting part is not that the API returns 529 — it is what a 529 or 500 does to work that is already in flight.

---

WHAT HAPPENED

Over a 41-hour window on one machine, 15 server-side API failures landed in Claude Code sessions:

| code | count | days |
|---|---|---|
| 500 Internal server error | 10 | 2026-07-28, 07-29 |
| 529 Overloaded | 5 | 2026-07-29, 07-30 |

Model attribution, verified from message.model in the transcripts rather than assumed:
14 of 15 were claude-opus-5. One 500 (2026-07-29T19:50:17Z, session 00fad5a9) was
claude-opus-4-8 and is named here only so it is not silently folded into an Opus 5 count.

Three of the 529s occurred within two minutes of filing this (2026-07-30T14:07:41Z, 14:07:51Z,
14:08:13Z), so the condition is live rather than historical.

---

THE COST, WHICH IS NOT THE ERROR ITSELF

A background subagent that is mid-unit is terminated outright. Twice in one session, a 500
killed an agent that had already written files to disk:

Agent "U15 person_id writer" failed: Agent terminated early due to an API error:
API Error: 500 Internal server error.

The first kill landed on the line "Now the positive control on the newly extracted predicates" — the
agent had finished 7 files and 498 insertions of real work and died before proving any of it. The
second kill landed on "Now the real interaction: pick a person, then close and reopen the sheet"
during its own render walk.

Nothing was lost, and that is the point: nothing was lost because a human-shaped recovery happened.
The parent session had to:

  1. notice the agent had died rather than finished,
  2. inspect the working tree to establish what survived (git status, a test run),
  3. and resume it by message so it did not start over.

Both resumes worked and kept the agent's context. But the recovery is entirely the parent's
judgement.
An orchestrator that treated the failure notification as "unit finished" would have
committed half-built work, and an orchestrator that treated it as "unit lost" would have thrown away
498 insertions and rebuilt them.

---

THE THREE THINGS WORTH LOOKING AT

1. Is a mid-flight subagent retried at all? A 529 is explicitly transient and the error text says
so: "usually temporary — try again in a moment." The parent turn is asked to try again; the subagent
is not. A one-line retry with backoff inside the agent runner would have made both of these
invisible.

2. The failure notification does not say what survived. It reports termination and a cause. It does
not report that the agent had written to disk, which is the single fact the parent needs to choose
between resume, discard and commit. The parent has to go and find out by hand.

3. A dynamic /loop turn is a single point of failure for the loop. In dynamic mode the next
wakeup is armed as the last action of the turn. If the turn dies on a 529 before that call, nothing
re-arms and the loop is over
, silently, with no notification that continuous work has stopped. This
was not proven from the transcript here and is raised as a design question rather than a confirmed
incident, but the shape is worth checking: it converts a transient server error into a permanently
stopped loop.

---

WHAT WOULD MAKE IT NOT MATTER

  • Retry 529 and 500 inside the agent runner before surfacing termination. These are the two codes

the product's own error text calls temporary.

  • Say what survived in the termination notification: files touched, or simply "the working tree was

modified".

  • Re-arm a dynamic loop's wakeup before the risky work, or re-arm it on turn failure, so a

transient error cannot end a loop that was asked to run continuously.

---

EVIDENCE

All timestamps UTC, extracted from ~/.claude/projects/-Users-shawnacason/*.jsonl by matching
Overloaded and Internal server error on real API-error records, with uuid and timestamp
false-positives excluded.

2026-07-28T17:39:19  500  claude-opus-5
2026-07-28T17:51:17  500  claude-opus-5
2026-07-29T10:39:13  529  claude-opus-5
2026-07-29T16:47:14  529  claude-opus-5
2026-07-29T19:50:08  500  claude-opus-5     <- killed background agent, mid-unit
2026-07-29T19:50:17  500  claude-opus-4-8   <- different session, NOT an Opus 5 incident
2026-07-29T19:50:37  500  claude-opus-5
2026-07-29T19:55:12  500  claude-opus-5
2026-07-29T19:56:28  500  claude-opus-5     <- killed the same agent again, mid-walk
2026-07-29T19:56:57  500  claude-opus-5
2026-07-29T20:08:58  529  claude-opus-5
2026-07-30T05:56:44  529  claude-opus-5     <- during an overnight dynamic /loop
2026-07-30T14:07:41  529  claude-opus-5
2026-07-30T14:07:51  529  claude-opus-5
2026-07-30T14:08:13  529  claude-opus-5

View original on GitHub ↗