Skip to content

bug(background-terminals): signal errors can settle a still-running child #591

Description

@ooiuuii

Background terminals can settle a live process after a failed signal

Problem

The background terminal manager treats every ChildProcess error event as a spawn failure. However, a process that has already started can emit error when a later signal operation fails, without exiting.

Currently that event marks the entry exited/failed and closes its full-log streams. The actual process may still run and produce output, while consumers have already received completion. Because the listener uses once, another such error also has no remaining manager listener.

Reproduction

Tested against main f6b49ae on Node 22.22.3, Windows. A real TerminalManager/ManagedRuntime starts a Node process that waits on an owned release file. After it prints a readiness marker, the test temporarily makes Node's native kill binding return libuv EPERM and calls the real child.kill("SIGTERM") method. Node emits kill EPERM; the child remains alive.

This is controlled fault injection at the native signal binding, not a claim that an ordinary Windows session naturally reproduced an OS permission denial.

Observed before the fix:

{"signalAccepted":false,"alive":true,"status":"failed","errorText":"kill EPERM","errorListenersBefore":1,"errorListenersAfter":0}

Expected: retain a running entry and error listener until real exit/close, preserve the bounded diagnostic, and capture output generated after the failed signal. A genuine spawn failure must still settle failed without exposing its errno as an exit code.

Scope

The affected owner is extensions/background-terminals/src/manager.ts. Its direct-signal fallback uses child.kill, so this is a valid lifecycle event contract. This report does not ask to change signal escalation, taskkill budgets, process-tree authority, tool schemas, or the shared process helper.

Related historical issue #408 / PR #412 concerns a different boundary: whether a timed-out taskkill helper permits a direct-shell fallback. This report concerns how the manager classifies an error emitted by the already-spawned child.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions