claude-code - 💡(How to fix) Fix [BUG] Bash tool sends SIGTERM instead of SIGINT when cancelling commands, corrupting build state [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#49233Fetched 2026-04-17 08:47:03
View on GitHub
Comments
0
Participants
1
Timeline
5
Reactions
0
Author
Participants
Timeline (top)
labeled ×4renamed ×1

When Claude Code cancels a running Bash command (timeout or user interruption), it sends SIGTERM directly. Build tools like ninja and make are designed to handle SIGINT gracefully — they finish the current write, flush state files, and exit cleanly. SIGTERM bypasses this, corrupting binary state files like .ninja_deps and .ninja_log.

Root Cause

When Claude Code cancels a running Bash command (timeout or user interruption), it sends SIGTERM directly. Build tools like ninja and make are designed to handle SIGINT gracefully — they finish the current write, flush state files, and exit cleanly. SIGTERM bypasses this, corrupting binary state files like .ninja_deps and .ninja_log.

Fix Action

Workaround

After an interrupted build, run ninja -t recompact to repair the deps log without a full rebuild. There is no way to prevent the corruption proactively.

Code Example

ninja: warning: premature end of file; recovering
RAW_BUFFERClick to expand / collapse

Summary

When Claude Code cancels a running Bash command (timeout or user interruption), it sends SIGTERM directly. Build tools like ninja and make are designed to handle SIGINT gracefully — they finish the current write, flush state files, and exit cleanly. SIGTERM bypasses this, corrupting binary state files like .ninja_deps and .ninja_log.

Problem

Ninja writes dependency information to .ninja_deps via fwrite(). When SIGTERM kills the process mid-write, the file ends up with a truncated record. On the next build, ninja reports:

ninja: warning: premature end of file; recovering

This loses dependency tracking information, causing unnecessary full rebuilds that can take significant time on large C++ projects. The only recovery is ninja -t recompact (if the file isn't too corrupted) or deleting the deps files and doing a full rebuild.

This affects any build system that relies on graceful shutdown to flush state: ninja, make, cargo, etc.

Expected behavior

Claude Code should use the standard signal escalation that terminals use:

  1. SIGINT first — equivalent to Ctrl+C. Build tools catch this, finish current I/O, and exit cleanly.
  2. Wait briefly (1–2 seconds) for the process to exit.
  3. SIGTERM if the process is still running.
  4. SIGKILL as a last resort.

This is what happens when a user presses Ctrl+C in a terminal, and it's what build tools are designed for.

Current behavior

Claude Code sends SIGTERM immediately (and there's a known issue #45717 where it hits the entire process group). There is no hook or setting to change the signal or the escalation sequence.

Workaround

After an interrupted build, run ninja -t recompact to repair the deps log without a full rebuild. There is no way to prevent the corruption proactively.

Environment

  • Claude Code on Linux (Fedora 43)
  • Ninja build system via CMake
  • Large C++ project where full rebuilds are expensive

Related issues

  • #45717 — SIGTERM propagation kills Claude Code itself, not just the child
  • #7841 — Feature request for a signal parameter on the Bash tool
  • #29096 — Graceful shutdown signal for headless sessions

extent analysis

TL;DR

Claude Code should be modified to send SIGINT before SIGTERM to allow build tools like ninja to handle the signal gracefully and prevent corruption of binary state files.

Guidance

  • To mitigate the issue, run ninja -t recompact after an interrupted build to repair the deps log without a full rebuild.
  • Consider implementing a custom signal escalation sequence in Claude Code, following the standard terminal behavior: SIGINT, wait, SIGTERM, and finally SIGKILL.
  • Review related issues #45717, #7841, and #29096 for potential solutions or workarounds.
  • If possible, explore adding a signal parameter to the Bash tool to allow customization of the signal sent to the build process.

Example

No code snippet is provided as the issue is more related to the signal handling behavior of Claude Code rather than a specific code implementation.

Notes

The provided workaround is not a permanent solution and may not work if the deps file is too corrupted. A more robust solution would involve modifying Claude Code to handle signals correctly.

Recommendation

Apply workaround: Run ninja -t recompact after an interrupted build to minimize the impact of the issue until a more permanent solution is implemented.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Claude Code should use the standard signal escalation that terminals use:

  1. SIGINT first — equivalent to Ctrl+C. Build tools catch this, finish current I/O, and exit cleanly.
  2. Wait briefly (1–2 seconds) for the process to exit.
  3. SIGTERM if the process is still running.
  4. SIGKILL as a last resort.

This is what happens when a user presses Ctrl+C in a terminal, and it's what build tools are designed for.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING