[BUG] claude ignores SIGINT despite a registered handler — Ctrl+C dead during startup hang, only SIGKILL works (Bun runtime)

Status Open
Reported on v2.1.233
Maintainer reply None cached
Activity 2 comments · opened Aug 18, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

SIGINT (Ctrl+C) is completely unresponsive while claude is hung during startup, even though the process has an active, registered SIGINT handler. Only SIGKILL terminates it.

This is not the common Ctrl+C confusion:

  • Not the Windows Terminal Ctrl+C-is-copy/paste keybinding conflict (Linux KVM guest, no Windows involved)
  • Not the intentional "press Ctrl+C twice to exit" UX — repeated Ctrl+C presses over several minutes had zero effect, not "needs a second press"
  • Not user impatience — the process was left running 6+ minutes, fully unresponsive to SIGINT the entire time (see linked hang issue for the CPU evidence)

The combination that makes this a real bug: SIGINT is not blocked (SigBlk = 0) and is registered with a handler (SigCgt bit 1 set), yet has zero observable effect.

What Should Happen?

Ctrl+C should reliably terminate the process regardless of what the main thread is doing internally. If SIGINT handling is implemented at the JS/application level, it should not be possible for an internal stall to starve the handler from ever running — a native/OS-level fallback capable of forcing termination independent of JS event-loop liveness would close this gap.

Error Messages/Logs

No error output at all — this is a silent, total hang. No stdout, no stderr, no exit.

Signal mask captured from the live hung process (`/proc/<pid>/status`):
State:    R (running)
SigBlk:   0000000000000000    # SIGINT is NOT blocked
SigCgt:   00000001280044fa    # bit 1 set → SIGINT DOES have a registered handler
Despite this, `kill -SIGINT <pid>` from another shell, and repeated terminal Ctrl+C, both had no effect. `kill -9` was required.

Steps to Reproduce

  1. On the affected environment (see below), run any of: claude, claude auth, or claude auth login --token <token>.
  2. Observe the process hangs (see #87554 for the underlying CPU-spin trigger).
  3. Press Ctrl+C repeatedly, or send SIGINT directly via kill -SIGINT <pid> from another terminal.
  4. Observe: no effect. Process must be killed with kill -9.

Claude Model

None
=> missing in the bug report select box a different platform:
_process never reached model selection; hung during startup before that step was ever reached_

Is this a regression?

I don't know

Last Working Version

unknown / first usage on this host

Claude Code Version

2.1.233

Platform

Anthropic API
=> missing in the bug report select box a different platform:
_Claude Pro/Max subscription OAuth token_ (via CLAUDE_CODE_OAUTH_TOKEN)

Operating System

Ubuntu/Debian Linux

Terminal/Shell

Other
=> missing in the bug report select box a different platform:
_ssh console / bash_

Additional Information

Runtime note: the claude binary here is a Bun-compiled executable (confirmed via live thread names mi-scavenger [mimalloc scavenger] and Bun Pool 0/Bun Pool 1), installed under an nvm-managed Node v24.19.0 bin path — Node itself is not the runtime actually executing.

Related issue, not a duplicate: #75561 (claude --resume hangs on account-level connector discovery) reports the same SIGINT-not-honored behavior during its own, mechanistically different hang (a network read stall vs. our CPU spin — see companion issue). The fact that SIGINT fails to rescue the user across two independent hang triggers suggests the gap in signal handling itself is systemic, not specific to either trigger. Worth fixing at the signal-handling layer rather than only patching each individual hang.

Corroborating pattern (not duplicates — different triggers, same failure mode):

  • #18532 — "Complete Freeze - 100% CPU, Main Thread Stuck in Infinite Loop" (macOS ARM64, Bun runtime, open): confirms the identical "Bun main-thread 100%-CPU infinite loop + Ctrl+C dead, only kill -9 works" signature, but triggered mid-session after ~2h of normal use rather than at startup.
  • #22240 — "Process hangs with 100% CPU (requires kill -9)" (closed as dup of #22042): same failure mode, additionally confirms SIGTERM is equally ineffective, not just SIGINT — reinforces this is a signal-handling gap in the Bun runtime path generally, not something specific to SIGINT alone.

Together these suggest the SIGINT/SIGTERM-unresponsive Bun main-thread spin is a recurring, version- and platform-spanning pattern rather than an isolated occurrence — this report adds the first documented startup-specific instance, correlated with CLAUDE_CODE_OAUTH_TOKEN being set.

Happy to provide the full /proc/<pid>/status, ps -T thread listing, or further captures on request.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗