Claude Batch Partial Failure — Some Requests Errored
Your batch completed with a mix of statuses: some succeeded, some errored, some canceled or expired. Batches ALWAYS end with per-request statuses — never assume all-or-nothing. Iterate results, retry errored ones in a new batch, and track completion via custom_id.
Iterate batches.results.list(batch_id), check each result.type (succeeded / errored / canceled / expired), extract data or error per case, and re-submit errored requests in a new batch. Always reconcile by custom_id. Log per-request status for post-mortem.
The Symptoms You're Seeing
batch.request_counts: succeeded: 87500 errored: 1200 canceled: 0 expired: 0 Some downstream records show empty results → You extracted only succeeded, dropped errored Rate limit errors on ~2% of requests → Some batches hit per-org concurrent limits during processing Silent data loss → Team assumed batch completed = all succeeded Cost anomaly (retried succeeded requests too) → No idempotency in retry logic; charged twice
Result Type Reference
| result.type | Meaning | Retry? |
|---|---|---|
succeeded | Request completed; result.message contains response | No |
errored | Request failed; result.error has details | Yes, if transient |
canceled | Batch was manually canceled before this request ran | Yes |
expired | 24-hour SLA exceeded; not processed | Yes, in new batch |
What Actually Causes Errors In Batches
Fixes That Work (Tested Nov 2026)
1Iterate All Results, Classify by Type
2Retry Errored Requests With Classification
3Full Reconciliation Pipeline
Use STABLE custom_ids across retry attempts. If you assign fresh IDs on retry, you can't track "already succeeded" and will re-run good requests. Always: custom_id = deterministic_from_source_record. E.g., user_42_summary_v1.
Preventing This Error Going Forward
- Never assume batches are all-or-nothing. Always iterate results.
- Classify errors: retryable vs terminal. Retry only what makes sense.
- Use stable custom_ids. Idempotent retries; no double-billing.
- Cap retry attempts (3 typical). Beyond that, human review.
- Save permanent failures separately. Track for manual investigation.
- Backoff between retry batches. Rate limits often clear in an hour.
Researcher · AI Error Hub
Frequently Asked Questions
Depends on error type. Requests that Claude processed and returned errors for count as billable tokens. Requests that failed validation without model invocation are not billed. Rate limit errors typically don't bill (though behavior varies). Check your invoice against your success count.
Yes: batches.cancel(batch_id). In-flight requests may still complete; requests not yet started are marked canceled in results. Useful when you realize you sent the wrong data.
All requests marked expired. Retry in a new batch, ideally after checking why: was there a queue congestion, was the batch too large, was your account quota exceeded? Anthropic status page usually explains.
Anthropic enforces uniqueness only within a single batch. Across batches, IDs can repeat. That's your problem — track "which batch produced which custom_id" if you need cross-batch reconciliation.
Cache doesn't help within a single batch (each request runs independently, no reuse). But if your batches share a common prefix across MULTIPLE batches processed sequentially within cache TTL, then yes. Rare optimization; ignore for most workloads.
Related Errors
Master Batch Reconciliation Patterns
Weekly deep dives on batch APIs, retries, and reliability. 12,000+ developers subscribe.
Subscribe Free →