CCDVF-D4.1 · Evaluation, Testing & Debugging2.6% of CCD-F9 min read

Debugging LLM System Failures.

A Claude application fails in two structurally different places: the integration layer (the call never reached a valid model turn - bad auth, malformed request, rate limit) or model output (the call returned 200, but the content is wrong - refused, truncated, or malformed). The error object only exists on non-2xx responses; a 200 with a bad stop_reason is not an HTTP error, so your code has to detect it itself.

Loading your plan…
Mental modelTreating every failure as retryable, or every malformed output as "hallucination" needing a prompt rewrite.
Debugging LLM System Failures, hero illustration featuring Loop mascot in a warm gallery scene.
Share
On this page
01 · Summary

TLDR

A Claude application fails in two structurally different places: the integration layer (the call never reached a valid model turn - bad auth, malformed request, rate limit) or model output (the call returned 200, but the content is wrong - refused, truncated, or malformed). The error object only exists on non-2xx responses; a 200 with a bad stop_reason is not an HTTP error, so your code has to detect it itself.

11
Typed HTTP error codes
CCDVF-D4
Exam domain
CCA-P D4 + CCA-A D7
Also tested in
2
Default SDK retries
3
Triage layers
02 · The decision

What you are deciding

Before fixing an LLM failure, decide which layer owns it: transport, request configuration or model output. Replay the recorded request several times, compare outcomes, and only then assign a cause.

Learner decision

Does this failure belong to transport, request configuration or the model's output?

03 · Definition

What it is

A production Claude call can fail in two structurally different places, and each needs a different fix. The integration layer covers everything before a valid model turn happens: bad auth, a malformed request, a rate limit, or a transient overload - these surface as non-2xx HTTP status codes with a typed error object (type, message, request_id). Model output failures are different in kind: the call returned 200, was billed, and completed - but the content itself is wrong, refused, truncated, or malformed. Confusing the two leads to the most common production debugging mistake: wrapping every call in a generic retry loop and shipping a truncated or refused response as if it were valid.

Origin isolation - deciding which of these two layers a given failure belongs to, before writing a fix - is the core skill this objective tests. It composes with two further steps: identifying the specific error TYPE once the layer is known, and selecting a recovery strategy that matches that type (retry with backoff, fix the request, raise max_tokens, adjust the prompt/policy, or enforce structure) rather than applying one generic reaction to every failure.

04 · By certification

How each certification frames it

CCD-F: How CCD-F tests debugging

  • CCDVF-D4-O1 Debugging and Error Handling: debugging and error handling techniques for Claude applications, including error type identification, recovery strategy selection, trace analysis to identify failure modes, and problem origin isolation between the integration layer and model output

The Developer guide lists error type identification, recovery strategy selection, trace analysis and problem origin isolation between the integration layer and model output (PDF page 7, Domain 4). The tested move is reproducing before explaining.

The API errors documentation lists status codes with error types, adds a request id to every response and error body, and says the official SDK retries transient failures with exponential backoff. It also notes that a streaming response can fail after a 200 status, with the error arriving as an event.

05 · Mechanics

How it works

Typed, predictable HTTP codes drive the first triage split. 400 invalid_request_error, 401 authentication_error, 402 billing_error, 403 permission_error, 404 not_found_error, 409 conflict_error, and 413 request_too_large are all non-retryable - the request itself is broken, so blind retry just repeats the failure. 429 rate_limit_error, 500 api_error, 504 timeout_error, and 529 overloaded_error are transient - retry with backoff genuinely helps. Getting this split backwards (retrying a 400, or treating a 429 as a code bug) is the most-tested distractor pattern.

SDKs retry automatically, but only within that transient set, and only twice by default. Connection errors, 429s, and 5xx responses are retried with exponential backoff honoring retry-after, configurable via a max_retries option per client. 429 responses also expose x-ratelimit-remaining-* headers for proactive throttling before a limit is hit. Catch typed SDK exceptions (e.g. Python anthropic.NotFoundError, anthropic.RateLimitError, anthropic.APIStatusError for any other non-2xx, anthropic.APIConnectionError for a network failure before any response existed) rather than string-matching error messages, and handle the most specific exception first. Every response - success or failure - carries a request-id for support correlation, the primary trace artifact for isolating a failed call.

Model-output failures live inside a 200 and surface only through `stop_reason`. stop_reason: "refusal" means Claude declined for safety - the call is 200 and billed, and the output may not match your schema because the refusal message takes precedence over schema constraints. stop_reason: "max_tokens" means truncation - the response may be incomplete and not match your schema either. Neither raises an exception; both require branching on stop_reason before the payload is trusted, which is precisely what a try/except around typed exceptions alone will not catch.

Structured Outputs and Strict Tool Use close the remaining JSON-quality gap, but they are two separate mechanisms, not one setting. Structured Outputs is configured via output_config.format on the request and constrains the model's final text response to a JSON Schema. Strict Tool Use is configured with a top-level strict: true field on an individual tool definition (alongside name, description, and input_schema) and constrains that tool's tool_use.input to its schema. output_config.format does not take a tool-level strict: true parameter - they are configured independently, on different objects, for different output paths (final response vs. a specific tool call), even though both compile to grammar-constrained decoding through the same underlying pipeline. Neither overrides a refusal or rescues a truncated response. One residual gap even under strict mode: enum/const values can differ only in leading-word capitalization with no error and no distinguishing stop_reason, so compare enum output case-insensitively rather than assuming exact-match. Exceeding schema complexity limits (20 strict tools per request, 24 optional params, 16 union-typed params) pushes the failure back to the integration layer entirely - a 400 before generation ever starts.

Origin isolation also covers prompt-design and model-selection failures, one level above HTTP/`stop_reason` mechanics. Not every wrong answer is a refusal or truncation - a well-formed, schema-compliant 200 can still be a hallucination (confident fabrication with no refusal signal), a prompt failure (ambiguous instructions producing a technically valid but off-target answer), or a model mismatch (a lighter/cheaper model handling a task past its reliability ceiling for that complexity). None of these raise a typed exception or an unusual stop_reason - they surface only through evaluation against ground truth or ground-truth comparison against a stronger model, which is why an architect's diagnostic toolkit extends past dev-level error handling into eval-driven root-causing.

Debugging LLM System Failures mechanics, painterly diagram featuring Loop mascot.
06 · Worked example

Worked example: a refund summary that sometimes comes back malformed

Authored teaching example, not a bank question.

Users report that the assistant sometimes returns a malformed refund summary. The team has a captured request.

01
Record everything. Store the exact model ID, parameters, system prompt, messages, tools and the request id of a failing call.
02
Freeze the setup. Replay the captured request unchanged. Do not switch the model version or edit the prompt while reproducing, or the results stop being comparable.
03
Replay repeatedly. Run it several times. Note the status code, the error type if any, and whether the output differs between runs.
04
Read the pattern. Match the pattern to a layer, as the table shows, and only then change something.
Replay resultLikely layerNext step
Some runs return an HTTP errorTransport or requestRead the error type and retry only transient errors
Every run returns the same wrong outputRequest configuration or inputInspect the recorded request for template or parameter faults
Status is 200 but output varies between runsModel output variabilityTighten the instruction and add output validation
One run passesInconclusiveKeep replaying before closing the issue

The team learns which layer to fix and can prove it by rerunning the same replay afterwards. Check that the fix is verified on repeated runs, not a single success.

07 · Failure modes

How this decision goes wrong

One successful replay closing the issue

Looks right: It worked on the second try, so it was a blip.

Why it fails: Model output varies between runs, so one pass proves little about the failure rate.

Instead: Replay repeatedly and compare outcomes before assigning a cause.

Changing versions during reproduction

Looks right: A newer model might fix it, so switch while testing.

Why it fails: You can no longer tell whether the failure moved because of the fix or the change. The models overview describes model IDs as pinned snapshots, so the recorded ID lets you reproduce exactly.

Instead: Replay with the recorded model ID and parameters first, and test changes afterwards as separate experiments.

Blanket retries

Looks right: Retrying every failure makes the system robust.

Why it fails: A request-validation error returns the same result every time, and retries add load and cost. Only transient errors are worth retrying.

Instead: Classify by error type: retry transient failures with backoff, fix invalid requests, and read the request id when escalating.

08 · In production

Where you'll see it

Ticket-extraction pipeline under load

Triage order: (1) did the call raise RateLimitError/APIStatusError - integration layer, fix with backoff/queuing; (2) if 200, read stop_reason first - max_tokens means raise the budget, refusal means fix policy/prompt, not retry; (3) only if stop_reason is end_turn/tool_use and JSON still fails to parse is it a genuine content-quality issue, fixed with output_config.format or strict: true.

Non-technical practitioner triage

A delivery consultant gets a vague, off-target answer from a client-facing Claude workflow - the CCAOF-D7-O1 framing treats this as a prompt-iteration problem (add specificity, examples, explicit format) before escalating it as a system-reliability incident.

09 · Compare

Side-by-side

↔ scroll to compare
Failure classHTTP statusSignalFix approach
Integration - transient429 / 500 / 504 / 529Typed error, retryableRetry with backoff (SDK does this automatically, twice by default)
Integration - non-retryable400 / 401 / 402 / 403 / 404 / 409 / 413Typed error, permanentFix the request/auth/schema; blind retry repeats the failure
Model output - refused200stop_reason: "refusal"Not an API error; adjust policy/prompt, don't retry the same call
Model output - truncated200stop_reason: "max_tokens"Raise the token budget; response may not match schema
Model output - malformed/non-compliant200end_turn/tool_use but JSON fails to parse or match schemaoutput_config.format / strict: true; compare enums case-insensitively
10 · Per certification

How each cert tests this

CCD-F

Developer (D4 · Evaluation, Testing & Debugging, CCDVF-D4-O1): tests the mechanical triage - typed HTTP error identification, retryable-vs-not classification, SDK exception handling, trace correlation via request_id, and isolating a failure to the integration layer vs. the model-output layer via stop_reason.

CCA-P

Architect - Professional (D4 · Evaluation, Testing & Optimization, CCARP-D4-O4): tests diagnosing system issues ONE LEVEL UP from HTTP mechanics - is a wrong-but-well-formed 200 a prompt failure (ambiguous instructions), a hallucination (confident fabrication), or a model mismatch (wrong model tier for the task's complexity)? None of these raise an exception or an unusual stop_reason.

CCA-A

Associate - Foundations (D7 · Troubleshooting & Optimization, CCAOF-D7-O1): tests the non-technical entry point into the same tree - recognizing that a vague, off-target, or poorly-formatted output is usually a PROMPT problem to iterate on (more specificity, examples, explicit format), not a system error requiring an engineering escalation.

11 · Exam trap

The exam trap

Treating every failure as retryable, or every malformed output as "hallucination" needing a prompt rewrite. In fact: (a) 400/401/403/404/413 never succeed on blind retry; (b) a 200 with stop_reason: "refusal" or "max_tokens" isn't an HTTP error, so code that only wraps calls in try/except around typed exceptions will silently ship truncated or refused content as valid; (c) structured outputs remove JSON-syntax failures but not schema compliance under refusal or truncation. The full objective - problem origin isolation between the integration layer and model output - is exactly this three-way split, not a single bucket.

Debugging LLM System Failures exam trap, painterly cautionary scene featuring Loop mascot.
12 · On the exam

Question patterns

CCD-F practice questions

5 approved CCD-F questions for this topic. Tap an answer to check it, then read the rationale for every option.

Question 1 of 5 · D4Choose the best answer

A production Claude call returns HTTP 200, but the JSON payload is truncated mid-object and fails to parse. The on-call engineer opens a ticket titled "API error: malformed JSON from Anthropic." Is this framing accurate?

Practice this topic with CCD-F questions

CCA-P practice questions

No approved public CCA-P sample question is published for this topic yet. The worked example above is an authored teaching example.

Practice this topic with CCA-P questions

CCA-A practice questions

No approved public CCA-A sample question is published for this topic yet. The worked example above is an authored teaching example.

Practice this topic with CCA-A questions

13 · FAQ

Frequently asked

Showing 5 of 5 questions

14 · Sources

Sources and next steps

CCD-F exam guide: Domain 4, Eval, Testing, and Debugging

Help someone pass

Share this concept.

One share is one less person stuck on the same question.

Last reviewed: ·Refresh cadence: monthly