Skip to content

fix(server): open stable Zed when a prerelease Zed is first on PATH - #9501

Open
EzraBuild wants to merge 2 commits into
pingdotgg:mainfrom
EzraBuild:fix/windows-zed-stable
Open

fix(server): open stable Zed when a prerelease Zed is first on PATH#9501
EzraBuild wants to merge 2 commits into
pingdotgg:mainfrom
EzraBuild:fix/windows-zed-stable

Conversation

@EzraBuild

@EzraBuild EzraBuild commented Sep 3, 2026

Copy link
Copy Markdown

What Changed

Zed's stable, preview, and nightly channels each install their own zed CLI. The editor launcher in externalLauncher.ts took the first zed found on PATH, so on a machine where a prerelease channel sits earlier on PATH, choosing "Zed" opened Zed Nightly or Zed Preview.

  • packages/shared/src/shell.ts gains resolveCommandPaths, which lists every PATH match for a command in order, reusing the existing PATHEXT handling and quote stripping. It never fails and is not cached.
  • The launcher uses it only for Zed: it prefers the first install whose location does not name a prerelease channel (nightly or preview) and, when that install is not the first on PATH, launches it by absolute path. A single install or an already correct PATH order keeps the bare command, so nothing changes for those users.
  • No environment or PATH rewriting, which is what the earlier attempt in fix(server): prefer stable Zed paths when opening in Zed #2066 was flagged for.

Tests: a launcher test puts a nightly zed.EXE ahead of a stable one on PATH and asserts stable launches by absolute path, then removes stable and asserts the bare command is kept. A shared test covers resolveCommandPaths ordering, explicit paths, and an empty PATH.

Why

Fixes #1978. The bug reproduces on Windows with Zed 1.18.0 stable and Zed Preview 1.19.0 installed side by side, both at %LOCALAPPDATA%\Programs\<channel>\bin\zed.exe, with the Preview bin first on PATH. Verified by launching through the real ExternalLauncher and checking which Zed process received the workspace:

PATH order Before After
Preview bin before stable bin Zed Preview opened the project Zed stable opened the project

UI Changes

None.

Checklist

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

Validation

  • vp test run apps/server/src/process/externalLauncher.test.ts (23 passed)
  • vp test run packages/shared/src/shell.test.ts (31 passed)
  • vp lint and vp fmt --check on the four changed files
  • vp run --filter @t3tools/shared --filter t3 typecheck

Model: Claude Fable 5.1. Harness: Claude Code.


Note

Low Risk
Scoped to Zed editor launch resolution with no PATH or env mutation; wrong heuristics could pick the wrong Zed binary on unusual install layouts.

Overview
When several Zed channels each expose a zed CLI, choosing Zed no longer always uses the first PATH hit (often Preview/Nightly).

resolveCommandPaths in shared shell code returns every executable match for a bare command in PATH order (Windows PATHEXT and quoting unchanged); it never fails and returns [] on an empty PATH. resolveZedCommand uses that only for the Zed editor: it picks the first install whose path is not treated as prerelease (isPrereleaseZedPath — a path segment must include both zed and nightly or preview). If that stable binary is not first on PATH, launch uses its absolute path; if stable is already first or only prerelease exists, behavior stays the bare zed command. Other editors still use first-available resolution. PATH is not rewritten.

Tests cover PATH ordering, nightly-only fallback, prerelease path classification, and resolveCommandPaths edge cases.

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

Note

Fix resolveEditorLaunch to prefer stable Zed over prerelease on PATH

  • Adds resolveCommandPaths to shell.ts which returns every matching executable in PATH order instead of only the first match
  • Adds isPrereleaseZedPath classifier to externalLauncher.ts that flags a path as prerelease when one component contains both "zed" and "nightly" or "preview"
  • Adds resolveZedCommand which scans all PATH matches and selects the first non-prerelease install, spawning it by absolute path when it is not the first match
  • resolveEditorLaunch now uses resolveZedCommand for Zed only; all other command-based editors keep the existing first-match resolver
  • Behavioral Change: Zed launches may now spawn a later stable executable by absolute path instead of the first PATH match; non-Zed editor resolution is unchanged

Macroscope summarized a36c424.

Zed's stable, preview, and nightly channels each install their own `zed`
CLI. The editor launcher took the first `zed` on PATH, so a machine with
a prerelease channel earlier on PATH opened Zed Nightly or Zed Preview
when the user chose "Zed".

Add `resolveCommandPaths` to the shared shell module, which lists every
PATH match for a command in order. The launcher uses it for Zed only:
prefer the first install whose location does not name a prerelease
channel and, when that is not the first on PATH, launch it by absolute
path. Single installs and correctly ordered PATHs keep the bare command,
so nothing changes for them. No environment or PATH rewriting.

Fixes pingdotgg#1978.

Model: Claude Fable 5.1. Harness: Claude Code.
@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Sep 3, 2026
Comment thread apps/server/src/process/externalLauncher.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at a36c424

Macroscope's review found this PR approvable — The change is narrowly scoped to correcting Zed executable selection when stable and prerelease installs coexist on PATH. Existing non-Zed launch behavior and normal single-install cases remain unchanged, with focused tests covering the new resolution path.

You can add or adjust custom eligibility rules. Learn more.

The prerelease check searched the full path for "nightly" or "preview",
so a stable Zed under a home directory like `C:\Users\preview-user`
was treated as prerelease. Check each path component on its own and
require it to name both Zed and the channel, which matches `Zed Preview`,
`Zed Nightly.app`, and `zed-nightly.app` but not unrelated folders.

Model: Claude Fable 5.1. Harness: Claude Code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 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 "Open in Zed" opens Zed Nightly instead of stable Zed

1 participant