Skip to content

Commit dbb3f2d

Browse files
basvandijkclaude
andauthored
fix(devcontainer): auto-install pinned rust toolchain in rust-analyzer (#10822)
## Problem Every time the dev container is rebuilt, the rust-analyzer VS Code extension fails to load the workspace: ``` FetchWorkspaceError: rust-analyzer failed to load workspace: Failed to load the project at /ic/Cargo.toml: Failed to read Cargo metadata from Cargo.toml file /ic/Cargo.toml, None: Failed to run `cd "/ic" && RUSTUP_AUTO_INSTALL="0" "/opt/cargo/bin/cargo" "metadata" ...`: `cargo metadata` exited with an error: error: toolchain '1.97.1-x86_64-unknown-linux-gnu' is not installed help: run `rustup toolchain install` to install it ``` The freshly built image does not contain the toolchain pinned in `rust-toolchain.toml` (`1.97.1`), and rust-analyzer runs `cargo` with `RUSTUP_AUTO_INSTALL=0`, so rustup refuses to install it on demand. The workspace stays broken until the toolchain is installed by hand (`rustup toolchain install`). ## Fix Override `RUSTUP_AUTO_INSTALL` back to `1` for rust-analyzer's `cargo` and `check` invocations via the dev container's `customizations.vscode.settings`: ```json "rust-analyzer.cargo.extraEnv": { "RUSTUP_AUTO_INSTALL": "1" }, "rust-analyzer.check.extraEnv": { "RUSTUP_AUTO_INSTALL": "1" } ``` rust-analyzer sets the `=0` default *before* applying `extraEnv` (see [`crates/toolchain/src/lib.rs`](https://github.com/rust-lang/rust-analyzer/blob/master/crates/toolchain/src/lib.rs)), so this override wins. rust-analyzer's own `cargo metadata` call then installs the pinned toolchain on demand, and the workspace loads without any manual step. ## Why a setting rather than a `postCreateCommand` / `postStartCommand` hook A lifecycle hook that runs `rustup toolchain install` was tried first but is fragile: if the install command exits non-zero (e.g. it runs before the container's network is ready) it **aborts the entire container rebuild**. A pure editor setting cannot break the rebuild, has no lifecycle-hook timing/`cwd`/`PATH` dependencies, and introduces no race with extension startup. ## Notes - This intentionally lets rust-analyzer trigger toolchain installs (upstream disables this by default to avoid surprise installs); that is exactly the desired behavior here, and it is scoped to this dev container rather than global user settings. - First workspace load after a rebuild takes slightly longer while the toolchain downloads; afterwards `rustup toolchain list` shows it too, since the install is global. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent cd72dfe commit dbb3f2d

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

.devcontainer/devcontainer.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@
7878
"bazel-ic/": true,
7979
"bazel-out/": true,
8080
"targets/": true
81+
},
82+
// rust-analyzer runs `cargo` with RUSTUP_AUTO_INSTALL=0, so a freshly
83+
// (re)built dev container that lacks the toolchain pinned in
84+
// rust-toolchain.toml fails to load the workspace until it's installed
85+
// by hand. Overriding it back to 1 lets rust-analyzer's own cargo
86+
// invocation install the pinned toolchain on demand. extraEnv is
87+
// applied after rust-analyzer sets the =0 default, so this wins.
88+
"rust-analyzer.cargo.extraEnv": {
89+
"RUSTUP_AUTO_INSTALL": "1"
90+
},
91+
"rust-analyzer.check.extraEnv": {
92+
"RUSTUP_AUTO_INSTALL": "1"
8193
}
8294
}
8395
}

0 commit comments

Comments
 (0)