CertSafari
    Anthropic Claude Certified Developer – Foundations (CCDV-F)· Lessons

    Domain 6 · Lesson 18/25

    Validating Claude responses before you use them

    Output Handling

    10 min read
    3.67% of exam
    3 sources
    Published 12 Oct 2026
    Docs as of 30 Sep 2026

    What you will be able to do

    • Check stop_reason first and handle end_turn, max_tokens, tool_use, pause_turn and refusal correctly
    • Recover from truncated tool calls and refusals without reusing incomplete output
    • Add an empty-content guard to a response-validation pipeline
    • Use grounding and citation checks to test whether well-formed output is actually correct

    1.Read stop_reason before the content

    Every successful Messages API response has a stop_reason field that says why Claude stopped generating. It is not an error. Errors mean the request failed, while a stop reason describes a completed generation. A response can be a 200 and still be unusable as an answer. Have your pipeline branch on stop_reason before it reads the content. That one field decides whether you use the response, continue it, retry it or send it to another model.

    stop_reason values and what your code should do
    stop_reasonWhen it occursWhat to do
    end_turnClaude finished its response naturally.Use the response.
    max_tokensThe response reached your max_tokens limit.Raise max_tokens or continue the response.
    stop_sequenceClaude emitted one of your stop_sequences.Read stop_sequence to see which one fired.
    tool_useClaude is calling a tool.Run the tool and return the result.
    pause_turnA server-tool loop reached its iteration limit.Send the assistant content back to continue.
    refusalClaude declined to respond.Read stop_details and retry on a fallback model.
    model_context_window_exceededThe response filled the model's context window.Treat the response as truncated.

    Checkpoint 1 of 7· Fill the gap

    Which stop_reason means the content is complete and safe to process?

    if response.stop_reason == " ? ":
        # Process the complete response
        for block in response.content:
            if block.type == "text":
                print(block.text)

    Sources1

    2.Truncated, tool and paused turns

    Three stop reasons mean the work isn't finished. With max_tokens and model_context_window_exceeded the output was cut off. Text that ends mid-thought is a fragment, not an answer, and it should never reach a parser or a user as if it were complete. You can usually continue a truncated text response. Tool calls are the exception: if the last content block is an incomplete tool_use, continuing won't produce usable arguments. Send the request again with a higher max_tokens.

    Detecting a tool call cut off by max_tokens and retrying with a larger limitpython
    # Check if response was truncated during tool use
    if response.stop_reason == "max_tokens":
        # Check if the last content block is an incomplete tool_use
        last_block = response.content[-1]
        if last_block.type == "tool_use":
            # Send the request with higher max_tokens
            response = client.messages.create(
                model="claude-opus-5-5",
                max_tokens=4096,  # Increased limit
                messages=messages,
                tools=tools,
            )

    tool_use means Claude is waiting for you. Run the tool and return its result. A server tool call that doesn't have its result block yet completes in a later response, so you don't answer it yourself. pause_turn means a server-tool loop hit its iteration limit. Send the assistant content back as it is, and Claude continues from where it stopped.

    Checkpoint 2 of 7· Check yourself

    A response stops with stop_reason "max_tokens", and its last content block is a tool_use. What should your code do?

    Checkpoint 3 of 7· Exam question

    A team builds a pipeline that extracts contact fields (name, email, plan) from support tickets and feeds them directly into a database insert without any try/except around the JSON parsing step. The pipeline occasionally crashes because Claude's response includes explanatory text before the JSON or omits a required field. What is the most effective fix to guarantee schema conformance without relying on prompt wording alone?

    Sources1

    3.Refusals arrive as successful responses

    Claude Fable 5.1, Fable 5, Opus 5.5, Opus 5 and Sonnet 5.5 include safety classifiers that can decline a request. A decline comes back as an ordinary response, so a pipeline that only catches exceptions will miss it. A loop that reads response.content[0] will crash on an empty list. A refusal looks like this:

    The shape of a refusal: empty content and a populated stop_detailsjson
      "content": [],
      "stop_reason": "refusal",
      "stop_details": {
        "type": "refusal",
        "category": "cyber",
        "explanation": "This request was declined because it could enable cyber harm."
      },

    Branch on stop_details.category, not on the explanation. The explanation text isn't stable, so show it to people and don't parse it. Both fields can be null when a refusal doesn't map to a named category, and that is a normal, permanent value. A refusal can also come mid-stream, after some output has already arrived. Discard that partial output rather than keeping it. To recover, send the same request to another Claude model. The beta fallbacks="default" setting does this on the server side, using the fallback model recommended for the refusal's category.

    Checkpoint 4 of 7· Check yourself

    A streamed response shows two paragraphs, then ends with stop_reason "refusal". What should happen to the two paragraphs?

    Sources2

    4.Guard against empty content

    A response can end with end_turn and still contain nothing. [Empty end_turn responses](lesson:4.1) usually appear after tool results, when Claude decides the turn is over. In a validation pipeline, that means end_turn alone isn't a passing check. Put the guard next to the stop-reason branch: if response.stop_reason == "end_turn" and not response.content:. Then handle that case explicitly instead of passing an empty list to a parser.

    The recovery is the part people get wrong. Sending the conversation back unchanged gets the same empty answer, because Claude has already decided it is done. First fix the message structure, so there are no text blocks straight after tool results. Only if that doesn't work, add a continuation prompt in a new user message.

    Checkpoint 5 of 7· Check yourself

    Your guard catches an end_turn response with no content blocks, and the message structure is already correct. What should the retry send?

    Sources1

    5.Well-formed output is not correct output

    A schema guarantees shape, not truth. Constrained decoding makes total_amount a float. It doesn't make it the total printed on the invoice. Fluent, well-formed text can still be wrong because of how [next-token generation and hallucination](lesson:5.1) work. A confidence: 0.92 field is also model output, constrained to be a number and nothing more. Treat confident, valid output as a claim to check against your sources.

    Several grounding and verification techniques turn that check into steps your pipeline can run:

    - Quote first: for long documents, have Claude extract word-for-word quotes before doing the task, and base the analysis only on those quotes. - Cite and retract: require a supporting quote for each claim, and remove any claim that has no quote. - Best-of-N: run the same prompt several times and compare the results. Inconsistencies across outputs could indicate hallucinations. - Allow uncertainty: give Claude explicit permission to say it doesn't have enough information, so it doesn't fill the gap. - Restrict knowledge: tell Claude to use only the provided documents and not its general knowledge.

    Quotes are what make this something code can verify. If the schema asks for the supporting quote next to each extracted value, your validator can check that the quote really appears in the source document before it accepts the record.

    Checkpoint 6 of 7· Match them up

    Match each verification technique to what it does

    Tap a term, then the definition that fits it.

    Checkpoint 7 of 7· Exam question

    A summarization service parses the response text as JSON. For very long transcripts, the JSON string is occasionally cut off mid-object and the parser raises a decode error. Investigating, the engineer finds stop_reason is "max_tokens" on every one of the failing calls. What should the defensive parsing logic do?

    Sources3

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.A refusal raises an API error, so try/except around the call is enough to catch it.Why is that wrong?

      A refusal is a successful 200 response with stop_reason "refusal" and possibly empty content. Only a stop_reason check catches it.

      Covered in Refusals arrive as successful responses

    2. 2.Any max_tokens stop can be fixed by asking Claude to continue.Why is that wrong?

      When the truncated content ends in an incomplete tool_use block, the request has to be retried with a higher max_tokens to get the full tool call.

      Covered in Truncated, tool and paused turns

    3. 3.Output that passes schema validation can be trusted as factually correct.Why is that wrong?

      Schema compliance only constrains shape. Claude can still produce content that is factually wrong or inconsistent with the context, so claims need grounding and citation checks.

      Covered in Well-formed output is not correct output

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “Check this field to decide whether to use the response as-is, continue the conversation, retry, or fall back to another model.”
      ↩︎ Read stop_reason before the content
      “Unlike errors, which indicate failures in processing your request, stop_reason tells you why Claude completed its response generation.”
      ↩︎ Read stop_reason before the content
      “A server tool call still missing its result block completes in a later response.”
      ↩︎ Truncated, tool and paused turns
      “Send the assistant content back to continue.”
      ↩︎ Truncated, tool and paused turns
      “if response.stop_reason == "end_turn" and not response.content:”
      ↩︎ Guard against empty content
      “Use continuation prompts as a last resort: Only if these fixes don't resolve the issue.”
      ↩︎ Guard against empty content
      “the truncated response contains an incomplete tool use block, you'll need to retry the request with a higher max_tokens value”
      ↩︎ Exam trap 2
      “the truncated response contains an incomplete tool use block, you'll need to retry the request with a higher max_tokens value”
      ↩︎ Checkpoint
      “Don't retry empty responses without modification: Sending the empty response back won't help.”
      ↩︎ Checkpoint
    2. 2.
      “The text is not stable, so display it rather than parse it.”
      ↩︎ Refusals arrive as successful responses
      “That null is a normal, permanent value, not a placeholder.”
      ↩︎ Refusals arrive as successful responses
      “When that happens, you receive a normal response, not an error, with stop_reason: "refusal".”
      ↩︎ Exam trap 1
      “A refusal is a successful HTTP 200 response with stop_reason: "refusal"”
      ↩︎ Prediction
      “In either case, treat any partial output as incomplete and discard it.”
      ↩︎ Checkpoint
    3. 3.
      “ask Claude to extract word-for-word quotes first before performing its task”
      ↩︎ Well-formed output is not correct output
      “Inconsistencies across outputs could indicate hallucinations.”
      ↩︎ Well-formed output is not correct output
      “Explicitly instruct Claude to only use information from provided documents and not its general knowledge.”
      ↩︎ Well-formed output is not correct output
      “can sometimes generate text that is factually incorrect or inconsistent with the given context”
      ↩︎ Exam trap 3
      “If it can't find a quote, it must retract the claim.”
      ↩︎ Checkpoint

    Ready to test yourself?

    Practise the 20 questions on this subdomain.

    Spotted a mistake, or was something unclear? Tell us.