Skip to content

Opening it in the IDE: open -a, code --wait, and a launcher pointing at a disk that is not there

Level: 101 · for newcomers

One line: The last line of a scratch script is open the folder in the editor, and on this Mac the obvious command for RustRover — rustrover "$dir" — prints a NSCocoaErrorDomain error and opens nothing, because the launcher on PATH was written by Toolbox in 2023 for an app that lived on a drive called T5; open -a RustRover "$dir" asks LaunchServices instead, which knows where the app went.

The four commands

Command What it does Returns
open -a RustRover "$dir" opens the folder as a project in the running RustRover, or starts it immediately
open -W -a RustRover "$dir" the same, then blocks when RustRover quits — not when the project closes
code --new-window "$dir" a new VS Code window on the folder immediately
code --wait --new-window "$dir" the same, then blocks when that window closes

The right-hand column is what decides which script can delete the project for you. VS Code's --wait is per window, so scratch.py --code removes the folder the moment you close it. RustRover's only waitable event is the whole IDE quitting — open's own help says -W blocks "until the used applications are closed (even if they were already running)", and measured here the call had still not returned a minute after the project was open — so scratch.py --rustrover deletes on the next run instead.

The launcher that is not

Real output — rustrover /tmp, the launcher on PATH
$ rustrover /tmp
The application /Volumes/T5/Applications/RustRover.app/Contents/MacOS/rustrover cannot be opened for an unexpected reason, error=Error Domain=NSCocoaErrorDomain Code=260 "The file “rustrover” couldn’t be opened because there is no such file."

/usr/local/bin/rustrover is a 20-line bash script, first line "Generated by JetBrains Toolbox 2.0.5.17700 at 2023-10-30", and its last line is open -na "/Volumes/T5/Applications/RustRover.app/Contents/MacOS/rustrover" …. The app is at /Volumes/T7/tools/RustRover.app today. Toolbox writes the launcher once, at install, with the path baked in; move the app and the launcher keeps the old path, and nothing on the machine notices until a script calls it. Two ways to fix it, and the second is the one the scripts here use:

  1. Regenerate it — Toolbox, Settings → Tools → Shell scripts, or delete the file and let Toolbox write it again.
  2. Do not use it. open -a RustRover resolves the app through LaunchServices, the same database Finder and Spotlight use, and lsregister -dump shows it holding the T7 path. That works from a script on any Mac where RustRover has ever been opened, whichever folder it is in.

code, by contrast, is a symlink into Visual Studio Code.app/Contents/Resources/app/bin/code, and the app is in /Applications; it is the one launcher here that has not moved.

What RustRover does with a folder from open -a

Real output — idea.log, after open -a RustRover on a scratch.sh project
2026-09-11 21:06:59,268 INFO - #c.i.i.i.ProjectUtil - Opening existing project with .idea at /private/var/folders/bc/gzwjtz8d6mx3l2f9yyf_p8yw0000gn/T/rust-scratch.cnwyCD

It opens the folder as a project, whether or not a .idea/ is there — that run had one, seeded by hand to test the next paragraph. The log says nothing about Cargo at open time; the attach shows up later, when the IDE syncs and then saves its workspace file:

Real output — idea.log, eleven minutes later, and the workspace.xml the IDE then wrote
2026-09-11 21:18:09,581 INFO - #org.rust.cargo.project.model.impl.CargoSyncTask - CargoSyncTask started
2026-09-11 21:18:10,245 INFO - org.rust.openapiext.CommandLineExt - Executing `/usr/local/opt/rustup/bin/rustup show active-toolchain` in working directory `/private/var/folders/bc/…/rust-scratch.cnwyCD`
2026-09-11 21:18:10,649 INFO - org.rust.openapiext.CommandLineExt - Executing `/usr/local/opt/rustup/bin/cargo metadata --verbose --format-version 1 --all-features …

  <component name="CargoProjects">
    <cargoProject FILE="$PROJECT_DIR$/Cargo.toml">

So the Cargo.toml at the root was attached — .idea/workspace.xml went from the six seeded lines to 77, with a CargoProjects component naming it, and a modules.xml and .iml beside it. What the log cannot say is whether that sync was the IDE's own doing or a click on the banner's Attach Cargo.toml button in the eleven-minute gap; either way it is once per project, and the folder from open -a ends up a real Cargo project.

The toolchain is a per-project IDE setting, not a file Cargo reads. A new project can open under No Rust toolchain specified even though cargo is on PATH, because RustRover keeps the toolchain path in .idea/workspace.xml and nothing auto-detects Homebrew's rustup shims. The value it wants is /usr/local/opt/rustup/binRustRover setup has the whole story. That is the component the test above seeded:

<project version="4">
  <component name="RustProjectSettings">
    <option name="toolchainHomeDirectory" value="/usr/local/opt/rustup/bin" />
  </component>
</project>

It was read: the sync above ran rustup and cargo from exactly that path, /usr/local/opt/rustup/bin/, and the component survived the IDE's rewrite of the file. So a scratch script can seed the toolchain and skip the Toolchain location dialog — which is what scratch.sh --rustrover does not yet do, and rust_scaffold.py could.

See also