What you will be able to do
- Explain why a generic "Operation failed" response stops an agent from choosing the right recovery
- Put retry and category metadata where the agent can read it, and give user-friendly explanations for business-rule failures
- Decide what a subagent should handle itself and what it should pass up to the coordinator, including partial results
- Tell an access failure apart from a successful query that returned no matches
1.Retryable vs non-retryable: give the agent what it needs to decide
Claude's tool-use documentation shows how the agent's reaction follows the error text. When the result says a required location parameter is missing, Claude calls the tool again with the gap filled. When the result says "ConnectionError: the weather service API is not available (HTTP 500)", Claude tells the user it couldn't get the weather and suggests trying again later. The same flag leads to two different recoveries, because the text tells the two cases apart.
Now replace both messages with "Operation failed". The agent can't tell a fixable argument from an outage, so it guesses. It might resend a request that will never succeed, burning turns on retries. Or it might give up on one that a corrected argument would have fixed. That is why uniform error responses rule out good recovery decisions: the agent's choice can only be as good as the information in the result.
The exam expects tools to make that information explicit and machine-readable: an errorCategory (transient, validation, permission), an isRetryable boolean, and a human-readable description. Those field names come from the exam guide. Neither the MCP specification nor the Claude docs define them. What the protocol does provide is somewhere to put them. A CallToolResult can carry structuredContent, described as a JSON object holding the result as machine-readable data and returned alongside content. The text in content still matters, because it is what the model reads as the explanation.
Business-rule violations need extra care. They are not retryable, so the result should say so clearly (the exam phrases this as retriable: false). The description should also be something the agent can pass on to a customer. The tutorial's calendar tool rejects an event with too many attendees, and Claude responds: "I tried to schedule the all-hands but the calendar only allows 10 attendees per event," then offers to split the session. Because the rule was stated plainly, the agent could explain it and suggest a way forward instead of retrying.
Checkpoint 1 of 5· Check yourself
A tool returns "Operation failed" with isError: true for timeouts, malformed dates and policy violations alike. What is the main consequence for the agent?
Claude chooses between retrying with corrected input, asking the user, or explaining the limitation based on what the error says. A generic message removes the information that choice depends on.
“Claude reads the error and can retry with corrected input, ask the user for clarification, or explain the limitation.”Source: platform.claude.com
2.Recover locally in the subagent and escalate only what's left
In a multi-agent system, the same reasoning decides where an error gets handled. A subagent that hits a transient failure is best placed to retry it, because it already has the context of the call. Passing every timeout up to the coordinator fills the coordinator's context with noise it can't act on any better. The exam's rule: retry transient failures inside the subagent, and send up to the coordinator only the errors the subagent couldn't resolve. When you do escalate, include the partial results and a record of what was attempted, so the coordinator can decide to reroute, retry elsewhere or report to the user without repeating work.
The sources don't describe this coordinator pattern directly. They do show the platform applying the same principle of keeping partial work. In Claude Code, if a rate limit, overload or server error cuts off a foreground subagent that has already produced text, the Agent tool returns that partial output with a note that the subagent was cut off. For a background subagent, the message Claude receives when it ends names the API error and includes the subagent's last output. In both cases the parent gets the error and the work done so far, not just a bare failure. Design your own subagent reports the same way.
Checkpoint 2 of 5· Check yourself
A research subagent gathered three of five sources, then failed on the fourth with an error it could not resolve after retrying. What should it return to the coordinator?
Escalate only what couldn't be resolved locally, and include partial results and the attempts made. Claude Code's own Agent tool likewise returns partial output with a note that the subagent was cut off.
“returns that partial output with a note that the subagent was cut off”Source: code.claude.com
Checkpoint 3 of 5· Exam question
A `deploy_service` MCP tool requires an API token scoped to the `deploy` role. An agent calls it using a token scoped only to `read`. The server returns `isError: true` with generic text "Operation failed." Under a structured error design, how should this failure be categorized and handled differently from a network timeout on the same tool?
Correct answer: A — As `errorCategory: "permission"` with `isRetryable: false`, since resubmitting with the same token will fail identically until the caller's scope changes
- A. Correct. An insufficiently scoped token is a permission error distinct from a timeout: it will never succeed on retry without a credential change, so isRetryable should be false and the category should reflect the access problem specifically.
- B. Incorrect. A timeout is about transient unavailability that may clear on its own; a scope mismatch is a fixed condition tied to the caller's credentials and won't resolve by waiting or retrying.
- C. Incorrect. The token isn't malformed input to be corrected by the caller's request shape; it's an authorization problem, and no amount of retrying with backoff changes what role the token carries.
- D. Incorrect. Business errors reflect policy rules about the request itself (like a return window), while this failure is about who is allowed to call the tool at all, which is the defining trait of a permission error.
Sources4
3.Access failures vs valid empty results
The last distinction runs in the opposite direction: a result that looks like a failure but isn't one. A query can fail to run because the database was unreachable or access was denied. Or it can run correctly and find nothing. These need opposite treatment. The first is an access failure, and the agent has to decide whether to retry. The second is a successful answer, "there are no matches", and the agent should report it as a fact.
The schema settles which is which. isError records whether the tool call ended in an error, and if it is not set, the call is treated as successful. A search that ran and matched zero records did not end in an error, so it should come back as a normal result whose content says no matches were found, with the flag left unset. Setting isError: true on an empty result misleads the agent. It may retry a query that already worked, or apologise to the user for a system failure that never happened. The reverse mistake is just as bad. If an unreachable backend returns an empty list with no flag, the agent will confidently report "nothing found" when it actually knows nothing.
Checkpoint 4 of 5· Check yourself
An order-lookup tool connects to its database, runs the query, and finds no orders for the customer. How should it respond?
isError indicates whether the call ended in an error. A query that ran and matched nothing succeeded, so it should come back as a normal result.
“If not set, this is assumed to be false (the call was successful).”Source: modelcontextprotocol.io
Checkpoint 5 of 5· Exam question
An MCP server exposes `update_inventory`. When the request body is missing the required `sku` field, the server currently returns `isError: true` with `errorCategory: "transient"` and `isRetryable: true`. An agent retries the exact same malformed request repeatedly and never succeeds. What is wrong with this error classification?
Correct answer: A — A missing required field is a validation error, not a transient one, so marking it retryable causes the agent to resend an identically malformed request instead of correcting the input
- A. Correct. A missing required field is a validation problem the caller must fix by changing the request, not a condition that resolves with time; labeling it transient and retryable misleads the agent into resending the same broken payload.
- B. Incorrect. Whether an error is a missing-field validation problem doesn't dictate protocol-level vs. tool-result reporting; a well-formed request with invalid field values is exactly the kind of business-logic-adjacent case reported via isError in the tool result.
- C. Incorrect. The field being supplied in some unrelated future request doesn't make this particular failed call retryable; the current request itself needs correction before it can succeed.
- D. Incorrect. The scenario explicitly shows the agent wasting retries on a request that can never succeed unmodified, which demonstrates the classification is causing the exact problem structured metadata is meant to prevent.
Sources5
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.A search that returns zero matches should be flagged with isError: true so the agent knows nothing came back.Why is that wrong?
isError means the call ended in an error. A query that ran successfully and found nothing is a valid result, and flagging it makes the agent retry or apologise for a failure that didn't happen.
Covered in Access failures vs valid empty results
2.Any error flagged with isError should simply be retried until it succeeds.Why is that wrong?
A business-rule violation gives the same answer on every retry. The right recovery is to explain the rule to the user, as Claude does when told the calendar caps attendees at 10.
Covered in Retryable vs non-retryable: give the agent what it needs to decide
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“ConnectionError: the weather service API is not available (HTTP 500)”
↩︎ Retryable vs non-retryable: give the agent what it needs to decide“the weather service API is not available. Please try again later.”
↩︎ Retryable vs non-retryable: give the agent what it needs to decide“If a tool request is invalid or missing parameters, Claude will retry 2-3 times with corrections before apologizing to the user.”
↩︎ Prediction - 2.
“structuredContent (optional): a JSON object holding the result as machine-readable data, returned alongside content.”
↩︎ Retryable vs non-retryable: give the agent what it needs to decide - 3.
“I tried to schedule the all-hands but the calendar only allows 10 attendees per event.”
↩︎ Retryable vs non-retryable: give the agent what it needs to decide“I tried to schedule the all-hands but the calendar only allows 10 attendees per event.”
↩︎ Exam trap 2“Claude reads the error and can retry with corrected input, ask the user for clarification, or explain the limitation.”
↩︎ Checkpoint - 4.https://code.claude.com/docs/en/sub-agentsOfficial docs
“returns that partial output with a note that the subagent was cut off”
↩︎ Recover locally in the subagent and escalate only what's left“the message Claude receives when it ends names the API error”
↩︎ Recover locally in the subagent and escalate only what's left - 5.
“Whether the tool call ended in an error.”
↩︎ Access failures vs valid empty results“If not set, this is assumed to be false (the call was successful).”
↩︎ Access failures vs valid empty results“Whether the tool call ended in an error.”
↩︎ Exam trap 1