Skip to content

tsc is not resposive to ctrl-c #63856

Description

When you run tsc and attempt to interrupt a build it does not respond instead it just complets the build

This is because typescript-go installs signal handlers to propagate sigterm and sigint to the context.Context object

However this is not always threaded all the way through the build

I prepared microsoft/typescript-go#4592 to fix this, but the fix is non-trivial

Alternatively should we just not install signal handlers and let normal behavior proceed?

Activity

  1. anthonyshew commented on Jul 15, 2026

    @anthonyshew

    Additional context: I ran into this separately from Luke (though also in a Vercel repo, as fate would have it!) and found these behaviors.

    Hangs when I do one ^C:

    ▲ 👟  pnpm run dev:ts
    
    > app@0.0.12 dev:ts /my/repo/path
    > tsc -b -w --preserveWatchOutput
    
    [10:19:06 AM] Starting compilation in watch mode...
    
    [10:19:07 AM] Found 0 errors. Watching for file changes.
    
    ^C
    

    Only exits after a third ^C:

    ▲ 👟  pnpm run dev:ts
    
    > app@0.0.12 dev:ts /my/repo/path
    > tsc -b -w --preserveWatchOutput
    
    [10:19:06 AM] Starting compilation in watch mode...
    
    [10:19:07 AM] Found 0 errors. Watching for file changes.
    
    ^C^C^C
    

    Exits immediately, as expected:

    ▲ 👟 pnpm exec tsc -b -w --preserveWatchOutput
    [10:20:10 AM] Starting compilation in watch mode...
    
    [10:20:10 AM] Found 0 errors. Watching for file changes.
    
    ^C
    
  2. rafaelnajman commented on Sep 8, 2026

    @rafaelnajman

    Confirming this on 7.0.2 and on 7.1.0-dev.20260908.1, macOS 15 arm64, with two consequences I didn't see covered here. I filed #64196 before finding this issue and am closing that one — moving the detail here.

    The interrupted compile exits 0. Clean 30,051-file / 1.9 M-line project, zero errors, 34 s baseline compile, signalled 10 s in:

    Signal Exit Result
    SIGINT 0 ran to completion (48 s), full --extendedDiagnostics block printed
    SIGTERM 0 ran to completion (49 s), full block printed
    SIGHUP 129 terminated at 10 s, no diagnostics
    SIGINT, idle --watch 0 exits in ~1 s, as expected

    "Ran to completion" isn't inferred from wall-clock timing — only a finished compile prints the Files / Lines / Check time / Total time block. SIGHUP is the useful control: it isn't in the signal.NotifyContext list, so it keeps its default disposition and dies instantly, which confirms the signals are reaching the process.

    The exit code matters beyond Ctrl-C being unresponsive: anything that terminates tsc — a CI job timeout, a cancelled workflow, a runner stopping a task — gets 0 back and records the build as having passed.

    Parallel build runners leak compilers. pnpm -r --parallel sends SIGTERM to the remaining packages when one fails, then exits. They ignore it, get reparented to PID 1, and keep compiling — uninterruptible, and no longer on the shell's job table so Ctrl-C can't reach them either. In our 17-service monorepo one failing service left the other 16 compiling, several above 2 GB each, until the machine ran out of memory. pnpm 12 escalates to SIGKILL and reaps them; pnpm 11 does not.

    A self-contained repro (generator + signalling script) is in #64196.

    One note for whoever picks this up: microsoft/typescript-go#4592 was closed unmerged on 2026-08-17 when typescript-go was archived, rather than on its merits — the migration notice said open PRs would be closed and need re-opening here, and that hasn't happened yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Needs InvestigationThis issue needs a team member to investigate its status.

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions