From 61392abf766a06487c05ff848a8ddba28171db92 Mon Sep 17 00:00:00 2001 From: Victor Vogel Date: Mon, 19 Oct 2026 23:16:16 -0500 Subject: [PATCH] fix(desktop): skip WSL distro probing while the WSL backend is off (#21225) Co-authored-by: Claude Opus 5.5 Co-authored-by: Julius Marminge (cherry picked from commit 4846ba8af7d038d851618bc7c64b143fc082a2e2) --- apps/desktop/src/ipc/methods/wsl.test.ts | 37 +++++++++++++++++++ apps/desktop/src/ipc/methods/wsl.ts | 6 +-- .../settings/ConnectionsSettings.tsx | 13 +++++-- 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/apps/desktop/src/ipc/methods/wsl.test.ts b/apps/desktop/src/ipc/methods/wsl.test.ts index 644597eaf451..34c3c9080eac 100644 --- a/apps/desktop/src/ipc/methods/wsl.test.ts +++ b/apps/desktop/src/ipc/methods/wsl.test.ts @@ -120,6 +120,43 @@ describe("WSL IPC", () => { ), ); + it.effect("does not enumerate distros until the WSL backend is enabled", () => { + const distros = [ + { name: "Ubuntu", isDefault: true, version: 2 as const }, + { name: "Debian", isDefault: false, version: 2 as const }, + ]; + const layer = Layer.mergeAll( + DesktopAppSettings.layerTest({ + ...DesktopAppSettings.DEFAULT_DESKTOP_SETTINGS, + wslDistro: "Debian", + }), + DesktopWslEnvironment.layerTest({ isAvailable: true, distros }), + layerWslBackend(), + layerLifecycle([]), + layerUnusedLifecycleRuntime, + ); + + return Effect.gen(function* () { + const wsl = yield* DesktopWslEnvironment.DesktopWslEnvironment; + const state = yield* getWslState.handler(undefined).pipe( + Effect.provideService(DesktopWslEnvironment.DesktopWslEnvironment, { + ...wsl, + listDistros: Effect.die("must not enumerate distros"), + }), + Effect.flatMap(decodeWslState), + ); + assert.equal(state.enabled, false); + assert.equal(state.available, true); + assert.equal(state.distro, "Debian"); + assert.deepEqual(state.distros, []); + + const enabledState = yield* invokeSetWslBackendEnabled(true); + assert.equal(enabledState.enabled, true); + assert.equal(enabledState.distro, "Debian"); + assert.deepEqual(enabledState.distros, distros); + }).pipe(Effect.provide(layer)); + }); + it.effect("stages dual-backend preferences before enabling without relaunching", () => { const relaunchReasons: Array = []; const layer = Layer.mergeAll( diff --git a/apps/desktop/src/ipc/methods/wsl.ts b/apps/desktop/src/ipc/methods/wsl.ts index 3c10f04512b4..6a36e87bbfcb 100644 --- a/apps/desktop/src/ipc/methods/wsl.ts +++ b/apps/desktop/src/ipc/methods/wsl.ts @@ -22,9 +22,9 @@ const readWslState: Effect.Effect< const wslBackend = yield* DesktopWslBackend.DesktopWslBackend; const settings = yield* appSettings.get; const available = settings.localEnvironmentEnabled && (yield* wslEnvironment.isAvailable); - // Only enumerate distros when WSL is actually available — listDistros on a - // non-WSL host would spawn wsl.exe and hit the timeout for nothing. - const distros = available ? yield* wslEnvironment.listDistros : []; + // Windows ships a wsl.exe stub that can prompt to install WSL when invoked. + // Keep disabled state reads from launching it to enumerate distros. + const distros = available && settings.wslBackendEnabled ? yield* wslEnvironment.listDistros : []; const preflightError = yield* wslBackend.lastPreflightError; return { enabled: settings.wslBackendEnabled, diff --git a/apps/web/src/components/settings/ConnectionsSettings.tsx b/apps/web/src/components/settings/ConnectionsSettings.tsx index ee0328f602fa..9f613f386659 100644 --- a/apps/web/src/components/settings/ConnectionsSettings.tsx +++ b/apps/web/src/components/settings/ConnectionsSettings.tsx @@ -3307,9 +3307,16 @@ export function ConnectionsSettings() { Off {desktopWslState.distros.length === 0 ? ( - - Default distro - + <> + + Default distro + + {desktopWslState.distro !== null ? ( + + {desktopWslState.distro} + + ) : null} + ) : ( desktopWslState.distros.map((distro) => (