Skip to content

orly-repl: piped-stdin EOF aborts in-flight entries and process.exit truncates their output #542

Closed

Description

@ohohoreilly

Found by #539's docker gate (printf '40 + 2;\n:quit\n' | docker run -i ... repl printed no result and exited 0), reproduced outside docker — any piped, non-interactive use hits it:

printf '40 + 2;\n' | orly-repl ...   # banner, one prompt, silence, exit 0

Two defects compound:

  1. EOF races the entry queue. Line handlers are serialized on a promise chain, but readline's close (stdin EOF) handler calls quit() immediately — closing the WebSocket and deleting the scratch dir while the first entry is still compiling/installing. The entry's rejection lands in the chain after quitting is set, and its prompt/result never print.
  2. process.exit(0) truncates pending pipe writes. The aborted entry's error text goes to stderr via console.error, whose write to a pipe is asynchronous; process.exit drops it. So the failure is silent — exit 0, no output — which is what made the CI log useless (11s of work, then nothing).

Fix: chain quit() onto the entry queue so EOF means "quit after pending entries drain" (interactive :quit/Ctrl-D semantics unchanged), and replace process.exit(0) with process.exitCode + natural event-loop drain so output always flushes. The smoke gains a piped-EOF scenario (lines written, stdin closed immediately — the exact CI shape).

Activity

  1. self-assigned this
    on Jul 7, 2026
  2. added 3 commits that reference this issue on Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions