Error codes
Every tool failure is one JSON envelope with a stable
errorcode. This page lists the codes and what triggers each. Match onerror, never onmessage.
The envelope
Every failure — for every tool — is serialized as a single JSON object:
json
{ "error": "<code>", "message": "<human-readable description>" }Some codes add fields (for example, a failing multi_edit reports the failing edit index in its message). The error value is one of the stable error codes; parse it, don't match on message text.
In DispatchResult terms: a failure sets isError: true and puts this JSON in text. Success never uses the envelope — its text is the tool's output (or, for bash, a { exit_code, … } JSON object, which is not an error even on a non-zero exit).
Codes
| Code | Meaning | Raised by (examples) |
|---|---|---|
invalid_input | Arguments failed schema or semantic validation. | Any tool (ajv); edit_file identical strings. |
not_found | Path does not exist — or the tool name is unknown/hidden. | All path tools; unknown/read-only-hidden tool. |
not_a_file | Path was a directory where a file was expected (or vice). | read_file, list_dir, write_file, apply_patch, bash (bad cwd). |
is_binary | File appears binary; text tools refuse it. | read_file, edit_file, multi_edit, apply_patch. |
no_match | old_string was not found. | edit_file, multi_edit. |
ambiguous_match | old_string matched more than once without replace_all. | edit_file, multi_edit. |
patch_failed | A patch hunk did not apply cleanly (names the file). | apply_patch. |
timeout | The command exceeded its timeout (partial output returned). | bash. |
output_limit | Output exceeded the hard capture ceiling; the command was killed. | bash. |
too_large | Input file exceeded maxFileBytes. | read_file, edit_file, multi_edit, apply_patch. |
path_escape | Path resolved outside the confined workspace root. | Any path tool when confineToWorkspace is on. |
io_error | An underlying filesystem or process error. | Any tool; bash spawn failure. |
internal | Unexpected internal error (details logged to stderr, not returned). | Any tool. |
Handling them
- Unknown / hidden tool →
not_found. Calling a tool that isn't registered — including a mutating tool whilereadOnlyis set — is anot_founderror, not a thrown exception. ambiguous_match/no_matchare recoverable. Feed the envelope back to the model so it can widen or narrowold_stringand retry. Seeedit_file.internalnever leaks details.serializeErrorlogs the stack to stderr and returns a generic{ "error": "internal", "message": "internal error" }— safe to surface to a caller.
See also
- Core API → Errors —
ToolError,serializeError,fsError,ErrorCode - The tools — which codes each tool can return
- createAgentTools → DispatchResult — how errors reach you