Stop hook does not fire when the CLI is terminated by SIGTERM (e.g. external execution timeout)

Resolved 💬 1 comment Opened May 30, 2026 by wtthornton Closed Jul 3, 2026

Summary

When the claude process is terminated by SIGTERM — for example, by a wrapper enforcing an execution timeout via timeout — the configured Stop hook never runs. Any state the Stop hook is responsible for emitting is left stale (it still reflects the previous successful Stop), so an external supervisor cannot tell "completed" apart from "killed mid-work."

Environment

  • Claude Code CLI 2.1.111
  • Linux
  • A Stop hook configured in .claude/settings.json

Expected

SIGTERM triggers a graceful-shutdown path that still fires the Stop hook (ideally with a flag/field indicating abnormal termination), or a dedicated termination hook fires, so downstream tooling can record that the run was killed rather than reading the prior run's hook output as if it were current.

Actual

SIGTERM kills the process with no Stop hook invocation. Downstream consumers that read the hook's output file see the previous run's content, with no signal that the current run was terminated.

Reproduction

  1. Configure a Stop hook that writes a marker file containing a fresh timestamp / run summary.
  2. Run a prompt that takes longer than the timeout under a wrapper: timeout 10 claude -p "<prompt that runs > 10s>" (or send SIGTERM to the claude PID manually).
  3. Observe the marker file is not updated — it retains the prior run's content.

Impact

An external timeout supervisor cannot distinguish a clean completion from a mid-work kill. In our case a loop that had edited files mid-work surfaced a completely unrelated prior run's summary (e.g. "backlog confirmed empty — stopping"), because the only status available was the stale Stop-hook output from an earlier iteration.

Downstream workaround (for context, not a fix)

Our wrapper now writes an explicit timeout status itself when it observes exit code 124, before reading any hook output — precisely because the Stop hook cannot be relied upon on SIGTERM. This is a band-aid.

Request

Either fire the Stop hook on SIGTERM with a field indicating abnormal termination, or provide a dedicated signal-safe termination hook / flush so supervisors can record a killed run. Happy to provide more detail or test a fix.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗