StopFailure
Runs instead of Stop when the turn ends due to an API error. Claude Code ignores the hook's output and exit code, apart from terminalSequence. Use this to log failures, send alerts, or take recovery actions when Claude can't complete a response due to rate limits, authentication problems, or other API errors.
StopFailure input
In addition to the common input fields, StopFailure hooks receive error, optional error_details, and optional last_assistant_message. The error field identifies the error type and is used for matcher filtering.
| Field | Description |
|---|---|
error | Error type: rate_limit, overloaded, authentication_failed, oauth_org_not_allowed, account_on_hold, billing_error, invalid_request, model_not_found, server_error, max_output_tokens, cloud_credential_error, or unknown |
error_details | Additional details about the error, when available |
last_assistant_message | The rendered error text shown in the conversation. Unlike Stop and SubagentStop, where this field holds Claude's conversational output, for StopFailure it contains the API error string itself, such as "API Error: Rate limit reached" |
json
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"hook_event_name": "StopFailure",
"error": "rate_limit",
"error_details": "429 Too Many Requests",
"last_assistant_message": "API Error: Rate limit reached"
}StopFailure hooks have no decision control. They run for notification and logging purposes only.