Skip to content

fix(ext/node): fix TLA stall with native TTY handles and make stdio indestructible#32792

Merged
bartlomieju merged 1 commit intomainfrom
fix/tty-tla-indestructible-stdio
Mar 18, 2026
Merged

fix(ext/node): fix TLA stall with native TTY handles and make stdio indestructible#32792
bartlomieju merged 1 commit intomainfrom
fix/tty-tla-indestructible-stdio

Conversation

@bartlomieju
Copy link
Copy Markdown
Member

Summary

  • Fix TLA (top-level await) stall detection to account for active native
    libuv-compat TTY handles. Without this, any await on readline/stdin
    with a non-stdout output stream (like @inquirer/prompts' MuteStream
    pattern) would immediately error with "Top-level await promise never
    resolved".
  • Make TTY process.stdout/process.stderr indestructible at the process
    level, matching Node.js's dummyDestroy behavior. Sets _isStdio = true
    to prevent Stream.pipe() from ending stdout when a piped source ends.
  • Add PTY integration tests for consecutive readline prompts (both direct
    stdout and PassThrough/MuteStream patterns).

Fixes #32782
Fixes #30747

Test plan

🤖 Generated with Claude Code

…ndestructible

Two fixes for issues introduced by the TTY rewrite (#32777):

1. The TLA stall detection in `poll_event_loop_inner` didn't consider
   `has_uv_alive_handles`, so active native TTY handles (e.g. stdin
   reading via readline) couldn't prevent the "Top-level await promise
   never resolved" error. This broke any code using `await` with
   readline/stdin when output was piped through a PassThrough stream
   (like @inquirer/prompts does).

2. TTY `process.stdout`/`process.stderr` were not made indestructible
   at the process level. Libraries like mute-stream call `destroy()`
   on stdout between prompts. Without the `dummyDestroy` override and
   `_isStdio` flag, the underlying TTY handle would be closed, breaking
   subsequent I/O. This matches Node.js's behavior in
   `lib/internal/bootstrap/switches/is_main_thread.js`.

Fixes #32782
Fixes #30747

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@nathanwhit nathanwhit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bartlomieju bartlomieju merged commit 6f4d5e9 into main Mar 18, 2026
112 checks passed
@bartlomieju bartlomieju deleted the fix/tty-tla-indestructible-stdio branch March 18, 2026 06:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants