Back to catalogue
ContextPostToolUseFailurePostToolUseFailureAfter tool failure · non-blocking· non-blocking
Structured tool failure log
Records every tool failure into a structured JSON file with timestamp, tool name, input and error, for debugging and auditing.
Use cases
- Debug tools that fail during autonomous sessions
- Detect recurring failure patterns
Providers & tags
Claude Code
#logging#debugging#failure#audit#error-tracking
settings.json fragment
{
"hooks": {
"PostToolUseFailure": [
{
"hooks": [
{
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/post-tool-failure-log.mjs",
"type": "command"
}
],
"matcher": ""
}
]
}
}Script · .claude/hooks/post-tool-failure-log.mjs
#!/usr/bin/env node
// Journalise les échecs d'outils pour le débogage (PostToolUseFailure)
import { readFileSync, appendFileSync, mkdirSync } from 'fs';
import { join } from 'path';
import { fileURLToPath } from 'url';
export function run(
input,
{
append = appendFileSync,
mkdir = mkdirSync,
projectDir = process.env.CLAUDE_PROJECT_DIR ?? process.cwd(),
now = () => new Date().toISOString(),
} = {},
) {
const logDir = join(projectDir, '.claude', 'data');
mkdir(logDir, { recursive: true });
const entry = {
ts: now(),
tool: input.tool_name ?? 'unknown',
input: input.tool_input ?? {},
error: input.error ?? input.tool_response ?? null,
};
append(join(logDir, 'tool-failures.jsonl'), JSON.stringify(entry) + '\n');
return { entry, message: `[post-tool-failure] Échec journalisé : ${entry.tool}\n` };
}
/* v8 ignore next 5 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
const input = JSON.parse(readFileSync(0, 'utf8'));
const result = run(input);
process.stderr.write(result.message);
}