Skip to content

fix: spawn server with node on Windows to avoid Bun PTY incompatibility#28

Merged
jesse23 merged 6 commits intomainfrom
debug/windows-disconnect
Apr 22, 2026
Merged

fix: spawn server with node on Windows to avoid Bun PTY incompatibility#28
jesse23 merged 6 commits intomainfrom
debug/windows-disconnect

Conversation

@jesse23
Copy link
Copy Markdown
Owner

@jesse23 jesse23 commented Apr 22, 2026

Summary

  • On Windows, bun run webtty disconnected immediately in the browser while bunx webtty worked fine
  • Root cause: two Bun-specific PTY paths both fail on Windows:
    • Bun.spawn({ terminal }) throws "terminal option is not supported on this platform"
    • @lydell/node-pty's ConPTY backend wraps named pipes using net.Socket({ fd }), which Bun's net.Socket does not support on Windows — resulting in pid=0 and ERR_SOCKET_CLOSED on the first write
  • bunx webtty works because its #!/usr/bin/env node shim runs the server process with Node.js, where node-pty's ConPTY backend works correctly
  • Fix: in startServer, when running on Windows under Bun, spawn the server with node instead of process.execPath — mirroring exactly what bunx does implicitly

Test plan

  • bun run webtty on Windows — browser opens, terminal connects and stays connected
  • bunx webtty on Windows — still works as before
  • bun run webtty on macOS/Linux — still works (condition is Windows-only)

🤖 Generated with Claude Code

jesse23 and others added 2 commits April 21, 2026 09:54
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On Windows, two Bun-specific PTY paths fail:
- Bun.spawn({ terminal }) throws "not supported on this platform"
- @lydell/node-pty's ConPTY backend uses net.Socket({ fd }) to wrap named
  pipes, which Bun's net.Socket implementation does not support on Windows,
  causing pid=0 and ERR_SOCKET_CLOSED on the first write

bunx webtty already works because its #!/usr/bin/env node shim runs the
server with Node.js, where node-pty's ConPTY backend works correctly.
Mirror that explicitly in startServer: on Windows under Bun, spawn the
server process with `node` instead of process.execPath.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adjusts the CLI server startup path to avoid Bun-specific PTY incompatibilities on Windows by spawning the server under Node.js when the CLI itself is running under Bun on Windows.

Changes:

  • Add Windows+Bun detection and select node as the server executable instead of process.execPath.
  • Document the rationale in startServer with a Windows/Bun/node-pty ConPTY explanation.
Comments suppressed due to low confidence (1)

src/cli/http.ts:70

  • Switching to serverExec = 'node' introduces a new failure mode where spawn can fail immediately (e.g. Node not on PATH) but startServer will still just poll until it times out and report "server did not start in time". Add explicit handling for child process spawn errors/early exit (and ideally a clearer message like "Node.js is required on Windows when running under Bun").
  const child = _spawn(serverExec, [serverEntry], {
    detached: true,
    stdio,
    env: { ...process.env, PORT: String(PORT) },
  });

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/cli/http.ts Outdated
- When serverExec is `node`, always resolve to the compiled `.js` entry
  since Node.js cannot execute `.ts` files directly (unlike Bun)
- Add a spawn `error` event handler so a missing `node` binary on PATH
  surfaces immediately with a clear message rather than timing out

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jesse23
Copy link
Copy Markdown
Owner Author

jesse23 commented Apr 22, 2026

Also addressed in fdade47: added a child.on('error', ...) handler so if node is not on PATH the process exits immediately with a clear message — "webtty: failed to start server: ... (Node.js must be on PATH when running webtty under Bun on Windows)" — instead of silently polling until the 10 s timeout.

jesse23 and others added 3 commits April 21, 2026 23:05
- Add `on` method to fakeChild mocks in http.test.ts so startServer's
  new spawn error handler doesn't throw in tests
- Cast process.exit to void-return type before the early return so the
  'server entry not found' test path exits cleanly when exit is mocked
- Replace noNonNullAssertion (session!) with optional chaining (session?)
  in websocket.test.ts to clear pre-existing biome lint warnings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jesse23 jesse23 merged commit ac42ffd into main Apr 22, 2026
3 checks passed
@jesse23 jesse23 deleted the debug/windows-disconnect branch April 22, 2026 03:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants