Error-Type Taxonomy (Transport, Request, Parsing, Model-Output, Tool-Loop)
PatternsDefinition
The five recognizable buckets a Claude application failure falls into -- transport/HTTP (429/529/5xx), request error (400/401), parsing/validation (a code-level exception reading the response), model-output error (well-formed but wrong content), and tool-loop error (wrong tool, malformed arguments, or a mis-fed tool_result). The bucket a failure falls into dictates the correct fix, and misclassifying it sends the fix to the wrong layer.
Example Usage
A crash while parsing Claude's response is a parsing/validation bug in the integration layer, not evidence the model is wrong -- add defensive parsing before concluding the model produced bad output.
In Depth
The Five Buckets
| Failure type | Where it lives | Signal |
|---|---|---|
| Transport/HTTP | Integration layer | 429 rate limit, 529/5xx overload, timeouts |
| Request error | Integration layer | 400 bad request, 401 auth, schema/max_tokens mistakes |
| Parsing/validation | Integration layer | Code throws when reading Claude's output (bad JSON, missing field) |
| Model-output error | Model output | Well-formed but *wrong*: hallucinated fact, missed instruction, wrong format |
| Tool-loop error | Integration <-> model | Wrong tool chosen, malformed arguments, tool result not fed back correctly |
Three of the five buckets live squarely in the integration layer (the caller's own code, request, and parsing logic); one lives in the model's actual output; tool-loop errors straddle both.
Why the Taxonomy Matters
The core discipline this taxonomy enforces: don't "fix" the prompt when the bug is in your code, and don't patch code when the model's output is the actual problem. Misclassifying which bucket a failure belongs to sends the remediation effort to the wrong layer entirely -- a parsing bug gets "fixed" by rewording the prompt (it won't help), or a genuine model-output error gets chased with defensive code changes (also won't help).
Localizing a Failure
A reliable procedure isolates the bucket: reproduce the exact failing request, inspect the raw response (status code, stop_reason, usage, content blocks) before any post-processing runs, then localize by what's observed -- non-2xx status points to transport/request; a 2xx response that crashes your own code points to parsing/validation; a 2xx response that parses cleanly but is substantively wrong points to model-output.
Recovery Follows the Bucket
Each bucket has a distinct correct recovery strategy: transient transport errors get retry-with-backoff; request errors need the payload or credentials fixed, not a retry; parsing errors need more defensive parsing; model-output errors need grounding, constraining, or an eval-driven prompt fix; tool-loop errors need better tool descriptions, schemas, or dispatch logic.
Common Pitfalls
- Treating a JSON parse crash on a successful (
2xx) response as evidence the model is wrong, when it's an integration-layer parsing bug. - Applying retry-with-backoff to a
400/401(request error), which will fail identically every time until the payload or credentials are fixed. - Treating a hallucinated fact the same as a transient server error -- one needs grounding and constraining, the other needs backoff and retry.