unixTerminal: input is silently queued forever when libuv threadpool completions stop arriving (CustomWriteStream has no watchdog)
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 52/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- electron, node.js, typescript
- Domain
- cli
Research direction
Start at CustomWriteStream.write() and _processWriteQueue(), focusing on how fs.write completion advances the queue. Run the FIFO-based deterministic reproduction and inspect the queue behavior when threadpool callbacks stop arriving. Done should include a defined recovery or failure signal for stalled input, backed by a regression test.
Written by the indexing model from the issue text.
Description
Environment
- node-pty 1.1.0 (
CustomWriteStreamwrite path from #833) - Electron app (pty host runs in a utility process), macOS 15 / darwin arm64
Issue
CustomWriteStream.write() queues data and relies on the async fs.write completion callback to advance the queue:
write()only starts processing when the queue transitions 0 → 1_processWriteQueue()issues onefs.writeand continues from its callback
fs.write completes on the libuv threadpool. If the pool stops delivering completions — which we observed live in production: all 4 workers idle in pthread_cond_wait, submitted work never picked up, event loop perfectly healthy — the callback never fires, the queue head never advances, and every subsequent write() appends to the queue forever. There is no error, no timeout, and no log: from the embedder's perspective the terminal simply stops accepting input while output (event-loop reads) keeps flowing. Terminal.write() returns void, so the embedder cannot observe or mitigate this from outside.
We confirmed this mechanism while investigating Orca's long-running "terminal intermittently stops accepting input" issue (stablyai/orca#8104). In the live wedged process, _writeQueue held every lost keystroke with the first task still at offset: 0, and hot-patching write to fs.writeSync restored input instantly — the fd was fine, only the threadpool path was dead.
We're investigating the Electron/libuv threadpool wedge separately. This issue is about how node-pty behaves when it happens: input stays queued indefinitely with no error and no recovery path.
Deterministic repro
The wedge can be simulated exactly by pinning every threadpool worker with a FIFO reader-open (blocks in open() until a writer appears):
const fs = require('fs');
const pty = require('node-pty');
const { execFileSync } = require('child_process');
execFileSync('mkfifo', ['/tmp/stall.fifo']);
const p = pty.spawn('/bin/sh', ['-c', 'read line; echo "GOT:$line"'], {});
p.onData((d) => process.stdout.write(d));
setTimeout(() => {
for (let i = 0; i < 6; i++) fs.open('/tmp/stall.fifo', 'r', () => {});
setTimeout(() => {
p.write('hello\n'); // never reaches the shell
fs.stat('/tmp', () => console.log('pool alive')); // never prints
}, 300);
}, 300);
- Dominant language
- TypeScript
- Stars
- 2k
- Forks
- 341
- Avg merge
- 13h 17m
- Merged PRs (30d)
- 5
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from microsoft/node-pty
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
ConPTY/TSFN exit callback aborts the process during environment teardown — fixable with NODE_API_SWALLOW_UNTHROWABLE_EXCEPTIONS (same root cause as #904)Possibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
microsoft/node-pty#951 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
All issues in microsoft/node-pty
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
Comfy-Org/ComfyUI_frontend#20346 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
decentralized-identity/didwebvh-ts#203 ·
Maintainers usually reply within 1 day
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
lingdojo/kana-dojo#31791 · 1 comment · 5 reactions ·
Maintainers usually reply within 1 day
-
Telegram webhook: line breaks lost since switch to rich messagesPossibly taken @Kshot3000 claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
github_actions security
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day