gotchas.md: Anthropic Batch request_counts.succeeded lags — never key a stall/cancel verdict on it
Highlight text on any card (body, plan, or an event) to anchor a comment, or leave a whole-task comment here. Mention @claude to summon a reply.
No comments yet.
Goal
Add an entry to .claude/rules/gotchas.md recording that an in-flight Anthropic
Message Batch can report request_counts.succeeded == 0 while being minutes from
completion, so a monitoring agent must never key a stall / drain / cancel verdict
on that counter. The reliable signal is the batch's own processing_status
transitioning to ended.
The incident (#823, 2026-08-20)
A 14,996-call generation wave ran as 15 sub-batches. The last one (sb1) sat at
processing=1000, succeeded=0 for 1 h 25 m on a congested org (93 in-flight batches /
521,829 requests processing, org-wide succeeded also 0). The session read that as
"not draining", CANCELLED the batch, and re-submitted its 1,000 calls on an idle org.
The cancelled batch then ended reporting succeeded: 997, canceled: 3 — it had
completed 997 of 1,000 requests and was ~minutes from done. Cost: 1,000 duplicated
calls ($2.3) plus 997 billed-and-discarded generations.
Corroborating observations from the same session, which make this a COUNTER property rather than a one-off:
- A different org showed
succeeded: 0summed across 8 in-flight batches holding 136,256 processing requests. - The wave's own other 14 sub-batches each read
processing=1000, succeeded=0while in flight, then appeared as complete — no intermediatesucceededvalue was ever observed across repeated sampling.
Why this belongs in gotchas.md
.claude/rules/gotchas.md is the always-on trap index for exactly this shape: an API
whose observable reads plausibly-but-misleadingly, where the wrong inference is
expensive and the right probe is one line different. Any agent monitoring a batch wave
(the eval.batch_judge poller path, a generation-wave driver, an ad-hoc watcher) can
reach for request_counts.succeeded as a progress signal and draw the same conclusion.
The neighbouring existing entries — the Batch-API empty-system-block 400, the
custom_id charset/length constraints, judge_pilot_gate satisfiability — cover
REQUEST-shape traps. This is the first MONITORING-side batch trap.
Proposed entry (draft; the implementer should sharpen)
Anthropic Batch
request_counts.succeededLAGS — an in-flight batch minutes from completion can reportsucceeded: 0, so a stall / drain / cancel verdict keyed on it is unsound. Measured (#823): a 1,000-request batch readprocessing=1000, succeeded=0for 1 h 25 m, was cancelled as "stalled", and ended reportingsucceeded: 997, canceled: 3; separately, 8 in-flight batches holding 136,256 processing requests summed tosucceeded: 0. RULE: key drain/liveness on the batch's ownprocessing_statustransition toended(and on the siblingrecently endedcount when judging an ORG's throughput), never onsucceededwhilein_progress. COROLLARY (the reasoning half): discovering that your progress signal is unreliable is evidence you CANNOT MEASURE the quantity — never evidence the quantity is zero; an unmeasurable value must not be promoted to a measured null to justify a destructive action. A batch queued within its 24 h SLA self-harvests for free (.claude/rules/auto-continuation.md§ FREE no-data-loss path) — cancelling to "unblock" it discards completed, billed work.
Acceptance criteria
- An entry in
.claude/rules/gotchas.mdcovering the counter behavior + theprocessing_status-keyed rule + the inference corollary, citing#823. - Placed near the existing Anthropic Batch-API entries (empty-system-block,
custom_idshape) so a reader hitting one finds the family. uv run python scripts/workflow_lint.pyclean (byte-budget checks included — gotchas.md is under a size ratchet, so if the entry pushes it over, relocate a topic-owned entry per the #2189 precedent rather than trimming this one).- No behavioral code change is required; if a repo-side monitoring helper is found
keying on
succeededwhilein_progress, fix it in the same round and name it.
Notes for the implementer
- Do NOT generalize to "
request_countsis unreliable" —processing,errored, and the terminal counts read correctly; the specific trap issucceededDURINGin_progress. - Whether the counter is genuinely non-incremental or merely coarse-grained was not established — the incident only establishes that a near-complete batch can read 0. Word the entry to that evidence; do not overclaim the mechanism.
- Check
src/explore_persona_space/llm/api_dispatch.pyandsrc/explore_persona_space/eval/batch_judge.pyfor any progress/stall logic readingsucceededmid-flight.
Provenance
Filed by the /issue 823 session (same-issue follow-up
inconsistent-origin-persona-ladder) after making exactly this error. Full incident
record: task #823 epm:progress v127.