zed/crates/cli
Kirill Bulatov d77425fe9c
Stop using wrong paths for zed --diff (#56380)
Closes https://github.com/zed-industries/zed/issues/56219

Contains 3 commist:
*
https://github.com/zed-industries/zed/pull/56380/changes/a8d55273d6cddb39868a1fd669c5069a1133a373
shows better errors when CLI or main binary fail early: no backtraces,
better error context, diff file paths shown

*
https://github.com/zed-industries/zed/pull/56380/changes/d389f7ee239dcf9bfa2bfe91729d96d2c1931663
stops opening Zed if cli `--diff` path argument(s) does not exist, also
switches over async fs API on the Zed side.
This is a behavior change, as before Zed tried to open or connect to an
instance — can be reverted if needed.

With `Path::exists` check CLI will do now:

<img width="669" height="55" alt="now"
src="https://github.com/user-attachments/assets/bdfbef2f-1b28-443d-8a01-0ff73ec0bba1"
/>

If I remove that bit, Zed will now open in the same cwd where the CLI is
invoked in:

<img width="1724" height="639" alt="reverted"
src="https://github.com/user-attachments/assets/69cd171b-aca3-445b-8647-5786f3360ce4"
/>


*
https://github.com/zed-industries/zed/pull/56380/changes/49787b7366336711b5bfc11ba3661f3ba70ce8ca
fixes an underlying bug leading to memory leak.

If on current `main`, I apply

```diff
diff --git a/crates/zed/src/zed/open_listener.rs b/crates/zed/src/zed/open_listener.rs
index 18ea7c0869..5db22521f2 100644
--- a/crates/zed/src/zed/open_listener.rs
+++ b/crates/zed/src/zed/open_listener.rs
@@ -791,6 +791,7 @@ async fn open_local_workspace(
     // working directory so the workspace opens with the right context.
     if !user_provided_paths && !diff_paths.is_empty() {
         if let Ok(cwd) = std::env::current_dir() {
+            log::error!("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ {cwd:?}");
             workspace_paths.push(cwd.to_string_lossy().into_owned());
         }
     }
```

I see the following logs:

```
2026-05-11T09:52:35+03:00 INFO  [zed] ========== starting zed version 1.3.0+dev.7bdcb6172263dc05c0b59be76e09f3e89e23e4f1, sha 7bdcb61 ==========
2026-05-11T09:52:36+03:00 INFO  [zed] Using git binary path: "/Applications/Zed Dev.app/Contents/MacOS/git"
2026-05-11T09:52:36+03:00 INFO  [util] set environment variables from shell:/bin/zsh, path:/opt/homebrew/opt/llvm/bin:/Applications/Postgres.app/Contents/Versions/16/bin/:/Users/someonetoignore/Developer/PlaydateSDK/bin/:/Users/someonetoignore/.docker/bin/:/opt/homebrew/opt/armv7-unknown-linux-gnueabihf/bin/:/opt/homebrew/opt/rustup/bin/:/opt/homebrew/opt/go@1.19/bin/:/usr/local/opt/llvm/bin/:/Users/someonetoignore/.jetbrains/bin/:/Users/someonetoignore/.cargo/bin/:/usr/local/git/bin/:/opt/homebrew/Cellar/openjdk@21/21.0.6//bin/:/Users/someonetoignore/.local/state/fnm_multishells/75815_1778482356501/bin:/opt/homebrew/opt/ruby/bin:/opt/homebrew/lib/ruby/gems/4.0.0/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/opt/pkg/env/active/bin:/opt/pmk/env/global/bin:/opt/X11/bin:/Library/Apple/usr/bin:/Applications/Wireshark.app/Contents/MacOS:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Users/someonetoignore/Library/pnpm:/opt/homebrew/opt/llvm/bin:/Applications/Postgres.app/Contents/Versions/16/bin/:/Users/someonetoignore/Developer/PlaydateSDK/bin/:/Users/someonetoignore/.docker/bin/:/opt/homebrew/opt/armv7-unknown-linux-gnueabihf/bin/:/opt/homebrew/opt/rustup/bin/:/opt/homebrew/opt/go@1.19/bin/:/usr/local/opt/llvm/bin/:/Users/someonetoignore/.jetbrains/bin/:/Users/someonetoignore/.cargo/bin/:/usr/local/git/bin/:/opt/homebrew/Cellar/openjdk@21/21.0.6//bin/:/Users/someonetoignore/.local/state/fnm_multishells/23413_1778480085615/bin:/opt/homebrew/opt/ruby/bin:/opt/homebrew/lib/ruby/gems/4.0.0/bin:/Users/someonetoignore/.cargo/bin:/Applications/iTerm.app/Contents/Resources/utilities:/Users/someonetoignore/.orbstack/bin:/Users/someonetoignore/.orbstack/bin
2026-05-11T09:52:36+03:00 INFO  [zed::reliability] Debug assertions enabled, skipping hang monitoring
2026-05-11T09:52:36+03:00 WARN  [zed::reliability] Minidump endpoint not set
2026-05-11T09:52:36+03:00 INFO  [extension_host] extensions updated. loading 21, reloading 0, unloading 0
2026-05-11T09:52:37+03:00 ERROR [crates/zed/src/main.rs:1936] canonicalizing "crates/grammars/src": No such file or directory (os error 2)
2026-05-11T09:52:37+03:00 INFO  [client] set status on client 0: Authenticating
2026-05-11T09:52:37+03:00 ERROR [zed::zed::open_listener] @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "/"
2026-05-11T09:52:37+03:00 INFO  [project::trusted_worktrees] Worktree "/" is not trusted
2026-05-11T09:52:37+03:00 ERROR [worktree] error reading target of symlink "/.VolumeIcon.icns": canonicalizing "/.VolumeIcon.icns": No such file or directory (os error 2)
2026-05-11T09:52:37+03:00 ERROR [worktree] error reading target of symlink "/Users/someonetoignore/.gitconfig.zed": canonicalizing "/Users/someonetoignore/.gitconfig.zed": No such file or directory (os error 2)
2026-05-11T09:52:37+03:00 INFO  [workspace] Rendered first frame
2026-05-11T09:52:37+03:00 ERROR [worktree] error reading target of symlink "/usr/lib/libnetwork.dylib": canonicalizing "/usr/lib/libnetwork.dylib": No such file or directory (os error 2)
2026-05-11T09:52:37+03:00 WARN  [fs] Failed to read symlink target metadata for path "/usr/sbin/weakpass_edit": Permission denied (os error 13)
2026-05-11T09:52:37+03:00 ERROR [worktree] error reading target of symlink "/usr/sbin/weakpass_edit": canonicalizing "/usr/sbin/weakpass_edit": Permission denied (os error 13)
2026-05-11T09:52:37+03:00 ERROR [worktree] error reading target of symlink "/usr/lib/libz.1.2.12.dylib": canonicalizing "/usr/lib/libz.1.2.12.dylib": No such file or directory (os error 2)
2026-05-11T09:52:37+03:00 ERROR [worktree] error reading target of symlink "/usr/lib/libpcre2-8.dylib": canonicalizing "/usr/lib/libpcre2-8.dylib": No such file or directory (os error 2)
2026-05-11T09:52:38+03:00 ERROR [worktree] error reading target of symlink "/var/run/docker.sock": canonicalizing "/var/run/docker.sock": No such file or directory (os error 2)
2026-05-11T09:52:38+03:00 ERROR [worktree] error processing "/var/db/DifferentialPrivacy": Operation not permitted (os error 1)
2026-05-11T09:52:38+03:00 ERROR [worktree] error reading target of symlink "/usr/lib/libipconfig.dylib": canonicalizing "/usr/lib/libipconfig.dylib": No such file or directory (os error 2)
2026-05-11T09:52:38+03:00 ERROR [worktree] error reading target of symlink "/private/var/run/docker.sock": canonicalizing "/private/var/run/docker.sock": No such file or directory (os error 2)
2026-05-11T09:52:38+03:00 ERROR [worktree] error processing "/private/var/db/DifferentialPrivacy": Operation not permitted (os error 1)
2026-05-11T09:52:38+03:00 ERROR [worktree] error processing "/Library/Caches/com.apple.amsengagementd.classicdatavault": Operation not permitted (os error 1)
2026-05-11T09:52:38+03:00 ERROR [worktree] error reading target of symlink "/usr/lib/libpcre2-posix.dylib": canonicalizing "/usr/lib/libpcre2-posix.dylib": No such file or directory (os error 2)
2026-05-11T09:52:38+03:00 ERROR [worktree] error processing "/Library/Caches/com.apple.aneuserd": Operation not permitted (os error 1)
2026-05-11T09:52:38+03:00 ERROR [worktree] error processing "/Library/Caches/com.apple.aned": Operation not permitted (os error 1)
```

According to
https://apple.stackexchange.com/questions/284754/what-is-the-default-working-directory-of-a-script-run-via-launchd
, the current directory of a running macOS app could be `/` if started
the way similar to how we do it via the CLI:


7bdcb61722/crates/cli/src/main.rs (L1306-L1329)

This means that every `std::env::current_dir()` is potentially dangerous
currently, as e.g. diff code tries to open this `/` as a worktree and
index it fully.
It seems that we're "ok" for now: the dangerous code is mostly in
extensions (there we set the cwd) and cli tools, and 2 places in
"development" Zed's code are left after this one is fixed.
There's one in `fs.rs` but that one is cfg-gated to Windows only hence
should not be an issue, at least the related one.

I'm not sure if this is the best way to fix the issue: setting `/` as an
app's current directory seems also wrong and maybe that invocation CLI
code could be altered somehow?
Maybe, `open_local_workspace` could be reworked somehow? 
Seems that now we need a "shared directory" for both files we diff which
seems inevitable though, hence I've went on with passing the CLI's
current dir when opening items and that fixes the `/` issue along with
the OOM for now.


Release Notes:

- Fixed a memory leak with diffing non-existing files with Zed cli
2026-05-11 15:53:20 +00:00
..
src Stop using wrong paths for zed --diff (#56380) 2026-05-11 15:53:20 +00:00
build.rs Fix Windows icon resource for bin zed.exe (#54738) 2026-05-01 22:33:54 +00:00
Cargo.toml Fix Windows icon resource for bin zed.exe (#54738) 2026-05-01 22:33:54 +00:00
LICENSE-GPL
README.md remote: Support line and column numbers for remote paths (#40410) 2025-10-17 10:50:22 +00:00

Cli

Testing

You can test your changes to the cli crate by first building the main zed binary:

cargo build -p zed

And then building and running the cli crate with the following parameters:

 cargo run -p cli -- --zed ./target/debug/zed.exe