InterviewPrepKit

Home / Coding / Agent Coding / Reliability & Retries / Classifying Tool Errors

Classifying Tool Errors

easy 00:00
Solving tips
  • Decide the category first, then derive retryable from it — only transient failures (timeouts, rate limits) are worth retrying.
  • Check the cheapest, most specific rule first: an unknown tool name is a hard failure no retry can fix, so screen it before you ever look at the exception.
  • Classify on both the exception type name and a lowercased message substring so you catch a timeout whether it arrives as TimeoutError or a RuntimeError('request timed out').

When an agent calls a tool and it fails, the loop needs to know what kind of failure it was before it can react. Retrying a rate-limited call is smart; retrying a call to a tool that does not exist, or a call with malformed arguments, just burns budget on a failure that will repeat identically. This exercise is the small classifier that sits between a failed tool call and the retry logic.

The categories

Sort every failure into exactly one bucket:

  • unknown_tool — the agent asked for a tool that is not in known_tools. No retry fixes a missing tool.
  • transient — a timeout or rate-limit / service-unavailable condition. The call might succeed if tried again, so this is the only retryable category.
  • validation — the arguments were malformed (invalid value, missing required field). Retrying the identical call repeats the failure.
  • tool_error — the tool ran but reported a domain failure of its own.
  • unexpected — anything that matches none of the above.

retryable is True for transient and False for every other category.

Task

Complete classify_tool_error(tool_name, error, known_tools) using simple rules on the error type and message:

  1. If tool_name is not in known_tools, return ("unknown_tool", False) before inspecting the exception.
  2. Otherwise look at type(error).__name__ and the lowercased str(error):
    • transient if the type is a TimeoutError / RateLimitError / ConnectionError / ServiceUnavailableError, or the message mentions a timeout, rate limit, “too many requests”, 429, 503, or “temporarily unavailable”.
    • validation if the type is a ValidationError / ValueError / TypeError / KeyError, or the message mentions “invalid”, “validation”, “required”, or “missing argument”.
    • tool_error if the type is a ToolError / RuntimeError, or the message contains “tool error”.
    • otherwise unexpected.
  3. Return (category, retryable) where retryable is True only for transient.

Check the rules in that order — the first matching category wins.

Example

known = {"search", "calculator"}

classify_tool_error("web_search", ValueError("bad"), known)
# -> ("unknown_tool", False)

classify_tool_error("search", TimeoutError("request timed out"), known)
# -> ("transient", True)

classify_tool_error("calculator", ValueError("invalid operand"), known)
# -> ("validation", False)

classify_tool_error("search", RuntimeError("upstream tool error"), known)
# -> ("tool_error", False)

classify_tool_error("search", MemoryError("out of memory"), known)
# -> ("unexpected", False)

Constraints

  • Return a (category, retryable) tuple; category is one of the five strings above.
  • retryable is True only when category == "transient".
  • Rule order matters: screen unknown_tool first, then transient, validation, tool_error, and finally unexpected.
  • Match on both the exception’s type name and a case-insensitive message substring; do not call any network or model.

Write your solution, then hit Run tests to check it — or get a mock grade from the AI coach.

The coach remembers this session — revise your code and ask again, and it grades your progress. It gives hints, not the answer.
Report a bug