Skip to content

fix(desktop): prevent WSL backend exiting with code 0 by keeping stdi…#3613

Open
jibin7jose wants to merge 3 commits into
pingdotgg:mainfrom
jibin7jose:fix-wsl-code-0-exit
Open

fix(desktop): prevent WSL backend exiting with code 0 by keeping stdi…#3613
jibin7jose wants to merge 3 commits into
pingdotgg:mainfrom
jibin7jose:fix-wsl-code-0-exit

Conversation

@jibin7jose

@jibin7jose jibin7jose commented Jun 30, 2026

Copy link
Copy Markdown

…n open

Fixes #3611 by appending Stream.never to the bootstrap stream so the Windows-side pipe does not close before the backend process completes reading it.

What Changed

Why

UI Changes

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Medium Risk
Changes affect WSL backend spawn/restart and stdin bootstrap paths on Windows; behavior is more defensive but alters when restarts stop and how failures surface.

Overview
Fixes WSL backends exiting with code 0 when bootstrap is delivered over stdin by keeping the parent pipe open: the bootstrap stream now appends Stream.never after the JSON line so the child does not see EOF while the server is still starting (#3611).

Desktop backend manager adds a neverReadyAttempt counter for stdin-delivery runs that exit before HTTP readiness. After five consecutive such exits it calls onPreflightFailed (same cap as fatal preflight) so the app can fall back to Windows instead of restarting forever; reaching readiness resets the counter. Windows fd3 delivery is unchanged.

WSL preflight now prints and parses nodeVersion: from the node-pty probe and rejects distros whose default Node does not satisfy the server engines range, with a clear fatal message instead of a silent exit.

Server bootstrap readline handling registers errors on the readline input interface (not only the raw stream), runs cleanup on error/line/close, and removes listeners from input so early stdin errors are handled reliably across the WSL pipe.

Reviewed by Cursor Bugbot for commit 215bd10. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Prevent WSL backend from exiting with code 0 by keeping stdin open

  • Keeps stdin open for stdin-delivery (WSL) backends by appending Stream.never after writing the bootstrap envelope in DesktopBackendManager.ts, preventing the child process from exiting cleanly when stdin closes.
  • Tracks consecutive pre-readiness exits for stdin-delivery backends; after reaching MAX_PREFLIGHT_FAILURE_ATTEMPTS, calls onPreflightFailed and either stops or restarts the backend.
  • Adds Node.js version detection to the WSL probe script in DesktopWslEnvironment.ts and validates it against a nodeEngineRange if provided, failing fast with a fatal error when the version is missing or incompatible.
  • Fixes error listener registration in bootstrap.ts to attach to the readline interface rather than the raw stream, ensuring cleanup runs on all error paths.
📊 Macroscope summarized 215bd10. 3 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.

…n open

Fixes pingdotgg#3611 by appending Stream.never to the bootstrap stream so the Windows-side pipe does not close before the backend process completes reading it.
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 16dda5e3-a16d-4022-b696-69187e1fe223

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Jun 30, 2026
Comment thread apps/desktop/src/backend/DesktopBackendManager.ts
@macroscopeapp

macroscopeapp Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces new WSL backend failure tracking and fallback logic, with multiple unresolved review comments identifying potential bugs: the neverReadyAttempt counter isn't reset on stop/start cycles, and there's a potential race between readiness detection and process exit. These issues could cause premature or incorrect fallback to Windows.

You can customize Macroscope's approvability policy. Learn more.

Tests using fd3 delivery were hanging because the stream never terminated. Only stdin delivery (WSL) needs the stream kept open.
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Jun 30, 2026
…gg#3611)

Consolidates fixes from PRs pingdotgg#3613, pingdotgg#3621, and pingdotgg#3623 to address both root causes and add a fail-safe:

1. DesktopWslEnvironment: Parse the Node version in the WSL node-pty probe and validate it against options.nodeEngineRange. Preflight now fails cleanly with an actionable error if the distro's default Node is incompatible.

2. DesktopBackendManager: Track neverReadyAttempt to cap consecutive post-spawn exits on stdin delivery. Prevents the desktop from permanently getting stuck restarting if the WSL backend consistently fails before readiness.

3. bootstrap: Clean up the readline interface on all event paths to prevent leaks when stdin stays open, and register the error listener on the readline interface to safely catch early stream errors.
@jibin7jose jibin7jose force-pushed the fix-wsl-code-0-exit branch from 340fb76 to 215bd10 Compare July 2, 2026 12:52
@github-actions github-actions Bot added size:L 100-499 changed lines (additions + deletions). and removed size:XS 0-9 changed lines (additions + deletions). labels Jul 2, 2026
@macroscopeapp macroscopeapp Bot dismissed their stale review July 2, 2026 12:52

Dismissing prior approval to re-evaluate 215bd10

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Medium

const { active, restartFiber } = yield* mutex.withPermits(1)(

stop() and a fresh manual start() never reset neverReadyAttempt, so a WSL backend that was stopped after a few pre-readiness exits inherits the old failure streak on the next start cycle. The new run can then trigger onPreflightFailed after a single additional exit, falling back to Windows even though the user initiated a fresh retry. Consider resetting neverReadyAttempt to 0 in both stop() and at the top of start() (alongside the existing preflightFailureAttempt reset).

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/desktop/src/backend/DesktopBackendManager.ts around line 807:

`stop()` and a fresh manual `start()` never reset `neverReadyAttempt`, so a WSL backend that was stopped after a few pre-readiness exits inherits the old failure streak on the next start cycle. The new run can then trigger `onPreflightFailed` after a single additional exit, falling back to Windows even though the user initiated a fresh retry. Consider resetting `neverReadyAttempt` to `0` in both `stop()` and at the top of `start()` (alongside the existing `preflightFailureAttempt` reset).

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 215bd10. Configure here.

) {
yield* mutex.withPermits(1)(
Effect.gen(function* () {
const { isCurrentRun, nextState, pid } = yield* Ref.modify(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Never-ready counter not reset

Medium Severity

The neverReadyAttempt counter for WSL backends isn't reset when the backend stops and restarts, unlike preflightFailureAttempt. This allows a partial failure count to persist across sessions, causing the WSL fallback mechanism to trigger prematurely after fewer new failures than intended.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 215bd10. Configure here.

const bootstrapStream = Stream.make(`${bootstrapJson}\n`).pipe(
options.bootstrapDelivery === "stdin" ? Stream.concat(Stream.never) : (s) => s,
Stream.encodeText,
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Readiness flag races process exit

Medium Severity

neverReadyAttempt uses latest.ready in finalizeRun, but readiness is set in a forked waitForHttpReady fiber while runBackendProcess awaits handle.exitCode on the main path. If the child exits right after the HTTP probe succeeds but before onReady updates state, a run that was actually ready can be counted as a never-ready failure.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 215bd10. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Windows desktop 0.0.28 gets stuck on connecting to WSL after enabling WSL support

1 participant