rust-lang/cargo · error

able to invoke rustc

Error message

able to invoke rustc

What it means

`detect_sysroot_src_path` computes the std source location and calls `ws.gctx().get_sysroot(&rustc).expect("able to invoke rustc")`. `rustc` was loaded one line above (`load_global_rustc`) and `get_sysroot` derives the sysroot by invoking that rustc. The expect treats rustc invocation as infallible because it just succeeded moments earlier; failure means rustc became un-invokable between the two calls.

Source

Thrown at src/compiler/standard_lib.rs:230

                None,
                false,
            ));
        }
    }
    Ok(())
}

fn detect_sysroot_src_path(ws: &Workspace<'_>) -> CargoResult<PathBuf> {
    if let Some(s) = ws.gctx().get_env_os("__CARGO_TESTS_ONLY_SRC_ROOT") {
        return Ok(s.into());
    }

    // NOTE: This is temporary until we figure out how to acquire the source.
    let rustc = ws.gctx().load_global_rustc(Some(ws))?;
    let src_path = ws
        .gctx()
        .get_sysroot(&rustc)
        .expect("able to invoke rustc")
        .join("lib")
        .join("rustlib")
        .join("src")
        .join("rust")
        .join("library");
    let lock = src_path.join("Cargo.lock");
    if !lock.exists() {
        let msg = format!(
            "{:?} does not exist, unable to build with the standard \
             library, try:\n        rustup component add rust-src",
            lock
        );
        match ws.gctx().get_env("RUSTUP_TOOLCHAIN") {
            Ok(rustup_toolchain) => {
                anyhow::bail!("{} --toolchain {}", msg, rustup_toolchain);
            }
            Err(_) => {
                anyhow::bail!(msg);

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Pin the toolchain (`rust-toolchain.toml`) and keep it installed for the whole build.
  2. Avoid uninstalling/swapping the active toolchain while Cargo runs.
  3. Re-run after the toolchain is stable; `cargo clean` if you switched versions.

Example fix

// before
let src_path = ws
    .gctx()
    .get_sysroot(&rustc)
    .expect("able to invoke rustc")
    .join("lib")
// after
let src_path = ws
    .gctx()
    .get_sysroot(&rustc)
    .with_context(|| "rustc became un-invokable while locating the sysroot; was the toolchain changed mid-build?")?
    .join("lib")
Defensive patterns

Strategy: validation

Validate before calling

// Confirm rustc is invocable and the sysroot is stable before relying on -Zbuild-std
use std::process::Command;
fn rustc_sysroot_ok() -> Option<std::path::PathBuf> {
    let out = Command::new("rustc").args(["--print", "sysroot"]).output().ok()?;
    if !out.status.success() { return None; }
    let p = String::from_utf8_lossy(&out.stdout).trim().to_string();
    Some(std::path::PathBuf::from(p))
}

Prevention

When it happens

Trigger: `rustc` binary deleted/moved after `load_global_rustc` (e.g. `rustup toolchain uninstall` mid-build); `RUSTC` env var changed; permissions on the rustc executable revoked mid-build; a broken `RUSTC_WRAPPER` that worked once and then failed.

Common situations: Concurrent toolchain uninstall/install; editor/IDE swapping `RUSTC_WRAPPER`; long-lived Cargo-as-library process outliving the toolchain it was started with; sandbox/CI that mutates PATH mid-run.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/891293624a9b68a6.json. Report an issue: GitHub.