Bedrock 429 handling is inconsistent for parallel subagents: pre-flight rejection kills the agent, mid-stream failure silently switches it to the ANTHROPIC_MODEL fallback

Status Open
Reported on v2.1.215
Maintainer reply None cached
Activity 2 comments · opened Jul 20, 2026

What's Wrong?

Running a Workflow with ~8 parallel subagents (high effort, each reading many files) on Bedrock exhausts the tokens-per-minute quota. The resulting failures take two different code paths with very different outcomes, and one of them silently changes the model mid-agent:

  1. Pre-flight rejection — Bedrock refuses the request at the quota gate with API Error: Request rejected (429) · Too many tokens, please wait before trying again. The subagent dies terminally on that turn (recorded as an isApiErrorMessage turn with "model":"<synthetic>"). No in-place retry, no backoff, no fallback — even though the error message literally says "please wait before trying again". The orchestration layer then has to re-spawn the whole agent from scratch (losing all its progress/context).
  1. Mid-stream failure — a request that was accepted but whose stream broke (observed as an assistant turn with an empty/aborted thinking block, zero error events in the transcript). This goes through the internal stream-retry path, which silently re-issued the turn on the model pinned in ANTHROPIC_MODEL (us.anthropic.claude-opus-4-8[1m] in my env) instead of the session/agent model (claude-fable-5). The agent then continued on Opus for the rest of its run. Nothing was surfaced — the only indications are the per-turn "model" fields in the transcript JSONL and the model badge in the /workflows TUI flipping to "Opus 4.8".

Why this matters

  • Asymmetry: the failure mode that could be retried cheaply (pre-flight 429, no tokens consumed) is terminal, while the one that got a partial response silently degrades/changes the model. Intuitively it should be the other way around, or at least consistent.
  • Silent model switch: for workflows that depend on a specific model (evaluation runs, model comparisons, cost control), a subagent quietly switching from the session model to the env-pinned fallback mid-conversation invalidates the run with no warning. At minimum this deserves a visible notice/log line, ideally an opt-out.
  • Wasted work: terminal 429 death discards the agent's whole context; a re-spawned agent re-reads everything (more tokens → more quota pressure → more 429s — the failure amplifies itself).

Evidence (from workflow transcript JSONL)

Timeline: 9 subagents started simultaneously at 16:51:20; two died on hard 429s 4–5 min in; every agent started after the burst subsided completed clean; one late agent hit the mid-stream failure and switched models:

16:51:20  9 finder agents start in parallel
16:55:43  agent A dies:  {"isApiErrorMessage":true, model:"<synthetic>",
          content:"API Error: Request rejected (429) · Too many tokens, please wait before trying again."}
16:56:08  agent B dies:  same terminal 429
...
17:43:55  agent C starts (re-spawn of a died dimension)
17:54:2x  agent C: fable-5 turn with empty/aborted thinking block (no error event),
          immediately followed by the same turn re-emitted with "model":"claude-opus-4-8";
          continues on Opus for the remaining ~9 turns

Dead-agent transcript tail (turn-level view):

ok   claude-fable-5
ok   claude-fable-5
ERR  <synthetic>   API Error: Request rejected (429) · Too many tokens, please wait before trying again.
<end of transcript — agent dead>

Fallback-agent transcript around the switch (line numbers from the JSONL):

line 54  user        tool_result (file read)
line 55  assistant   model=claude-fable-5   thinking block empty/aborted, no error flag
line 56  assistant   model=claude-opus-4-8  same turn re-emitted; all subsequent turns on Opus

Expected Behavior

  • Pre-flight 429s ("please wait before trying again") should get bounded backoff-and-retry on the same model before the turn is declared terminal, matching how mid-stream failures are retried.
  • If a fallback to ANTHROPIC_MODEL (or any model other than the one the agent was launched with) happens, surface it: a system line in the transcript, a notice in the workflow/agents UI, or at least a structured log event — and ideally a setting to disable cross-model fallback for consistency-sensitive runs.

Related issues (adjacent, not duplicates)

  • #68816 — rate-limit/usage-limit is recorded as a synthetic assistant turn with terminal stop_reason: stop_sequence, indistinguishable from a clean completion. That's the transcript-representation side of failure mode 1 here (why orchestration sees the agent as "done" rather than "parked").
  • #64328 — workflow harness retry behavior on 429 without backoff/circuit-breaker, amplifying token burn. That's the orchestration-layer amplification of failure mode 1 (each respawned agent re-reads everything under an already-exhausted quota).

Neither covers the silent cross-model fallback on mid-stream failure (failure mode 2), which is the main new report here; filing separately per the one-bug-per-issue guideline but linking for triage.

Environment

  • Claude Code 2.1.215, macOS (Darwin 25.5.0)
  • Provider: Bedrock (CLAUDE_CODE_USE_BEDROCK=1, AWS_REGION=us-east-1)
  • Session model: us.anthropic.claude-fable-5; env: ANTHROPIC_MODEL=us.anthropic.claude-opus-4-8[1m]
  • Repro context: Workflow tool with 8 parallel high-effort subagents doing code review over a ~10k-line repo; concurrency cap 10 (12-core machine)

Is this a regression?

Unknown — first time running this many high-effort parallel subagents on this account/quota.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗