Skip to content

[Bug]: on Windows, killing a terminal leaves the process alive for five extra seconds #22

Open

Description

@antianqi

Product or interface: Desktop app
Version: node-pty 1.1.0, Windows 11 x64 (10.0.26100)
Platform: Windows
OS version and architecture: Windows 11 x64 (10.0.26100)
Issue area: Tool call / permission / sandbox

What happens

On Windows, killing a terminal leaves the process alive for about five seconds longer than it has any work to do.

node-pty's Windows ConPTY kill path forks a helper (conpty_console_list_agent) to enumerate the processes attached to the shell's console, so that a killed terminal cannot leave detached processes behind. A shell hosted by ConPTY has a pseudo-console, not a console, so the helper's AttachConsole always fails there. The helper dies without answering, and node-pty falls back to a five-second timer to resolve the promise.

That timer lives in the process that killed the terminal. Every kill therefore leaves that process with five seconds of pending work it did not ask for.

Measured

Killing five powershell.exe terminals on this host:

kill -> exit events finished at   720 ms
the process was still alive at   5740 ms
one "Error: AttachConsole failed" per terminal

The AttachConsole failed lines are also what shows up in the CI logs of the native PTY acceptance case, which is what made its shutdown hook miss its deadline. That case is fixed (#17) by having the host exit once it has reported; the drag itself is still there.

What it costs

  • The desktop app takes about five extra seconds to quit after the WebUI service closes with a terminal open.
  • Any process that opens a terminal and then exits pays the same five seconds.

What was tried

node-pty's useConptyDll option skips the helper entirely (the shipped prebuilds/win32-x64/conpty/conpty.dll is present). Measured on this host it is worse: the process did not exit at all.

What would help

Either:

  • a node-pty change that unrefs the fallback timer, or that attaches to the pseudo-console instead of a console; or
  • a way for the host to stop waiting on that promise — the kill itself is synchronous, only the promise resolution is delayed.

The repository cannot fix this from its own side: the timer is internal to node-pty and the handle is not reachable from outside.

Activity

  1. antianqi commented on Nov 10, 2026

    @antianqi
    CollaboratorAuthor

    PR #17 (merged as c32bfcd) now works around this in the acceptance host: the host exits as soon as it has reported, so the acceptance case no longer pays the five seconds. The case went from 13-15s to about 8.5s, and it now fails loudly if the host has not exited within two seconds of reporting.

    The root cause is still in node-pty and still affects every other caller on Windows. node-pty 1.1.0 forks conpty_console_list_agent on every kill to enumerate the processes attached to the shell's console. A shell hosted by ConPTY has a pseudo-console rather than a console, so the helper's AttachConsole always fails there; the helper dies without answering, and node-pty resolves the promise from a five-second fallback timer that lives in the process that killed the terminal. Measured on a Windows host: killing five terminals finished in 720ms, but the process stayed alive for 5.74s, and each terminal printed Error: AttachConsole failed.

    useConptyDll: true skips the helper entirely and was measured too: the process did not exit at all, so it is not a workaround.

    So this issue is about node-pty itself: the five-second fallback should not be the only path, and the helper failing should be surfaced rather than silently absorbed.

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