Skip to content

Windows/ConPTY: writing to a killed pty emits EAGAIN on an untended inSocket -> uncaught exception #976

Description

Environment: node-pty 1.1.0 · Windows 11 (26200) · ConPTY (useConpty: true, non-DLL path) · reproduced on Node 22.x

Description

On Windows, writing to a pty's stdin (conin) shortly after its child process has exited fails asynchronously with write EAGAIN. The write goes to WindowsPtyAgent._inSocket, which is created without any 'error' listener (windowsPtyAgent.js ~L82). The 'error' handler in windowsTerminal.js (L80) is attached to _socket = _agent.outSocket (the read side), not the write side. So the socket emits 'error' with no listener and the process throws:

Error: write EAGAIN
    at WriteWrap.onWriteComplete [as oncomplete] (node:internal/stream_base_commons:87:19)

This is not catchable by the caller: IPty.write() returns normally and the failure surfaces later on the write-completion callback. IPty does not forward inSocket errors (_forwardEvents only wires _socket/outSocket), so a consumer cannot subscribe through the public API either.

Minimal repro (Node, no Electron)

const pty = require('node-pty')
const p = pty.spawn('cmd.exe', ['/k', 'echo hi'], { useConpty: true, cols: 80, rows: 24 })
setTimeout(() => { p.kill(); setTimeout(() => p.write('x'), 2000) }, 800)
// ~a couple seconds later: uncaught "write EAGAIN" from the inSocket

Timing-dependent: the conin pipe's 128 KB buffer stays writable briefly after death, then rejects with EAGAIN.

Expected

A write to a dead pty's stdin is dropped or surfaced as a catchable error — never an uncaught exception.

Suggested fix

Attach an 'error' handler to _inSocket (mirroring the outSocket handler), and/or forward its errors through IPty so consumers can handle them.

Downstream report

obogoni/playground#103

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