rust-lang/cargo · error
already loaded without errors
Error message
already loaded without errors
What it means
On the nightly-only shell-completion path in `cargo`'s `main`, `GlobalContext::default().expect("already loaded without errors")` constructs the global config a second time inside the `clap_complete::CompleteEnv` factory. It already succeeded once at the top of `main`, so the second call is expected to succeed too. The panic indicates a transient or environment-driven failure on the reload — config files changed between the two calls, a HOME/CARGO_HOME race, or filesystem error.
Source
Thrown at src/bin/cargo/main.rs:34
fn main() {
let _guard = setup_logger();
let mut gctx = match GlobalContext::default() {
Ok(gctx) => gctx,
Err(e) => {
let mut shell = Shell::new();
cargo::exit_with_error(e.into(), &mut shell)
}
};
let nightly_features_allowed = matches!(&*features::channel(), "nightly" | "dev");
if nightly_features_allowed {
let _span = tracing::span!(tracing::Level::TRACE, "completions").entered();
let args = std::env::args_os();
let current_dir = std::env::current_dir().ok();
let completer = clap_complete::CompleteEnv::with_factory(|| {
let mut gctx = GlobalContext::default().expect("already loaded without errors");
cli::cli(&mut gctx)
})
.var("CARGO_COMPLETE");
if completer
.try_complete(args, current_dir.as_deref())
.unwrap_or_else(|e| {
let mut shell = Shell::new();
cargo::exit_with_error(e.into(), &mut shell)
})
{
return;
}
}
let result = if let Some(lock_addr) = cargo::ops::fix_get_proxy_lock_addr() {
cargo::ops::fix_exec_rustc(&gctx, &lock_addr).map_err(|e| CliError::from(e))
} else {
let _token = cargo::util::job::setup();View on GitHub (pinned to 0e07a15537)
Solutions
- Re-trigger completion after the config file write finishes.
- Ensure `HOME` and `CARGO_HOME` point to a stable, readable directory.
- Check permissions on `~/.cargo/config.toml` and the credentials file; `chmod u+r` if needed.
- If it reproduces, capture `RUST_LOG=cargo::util::context=trace` output and file a Cargo bug — the second load should arguably fall back rather than panic.
Example fix
// before
let mut gctx = GlobalContext::default().expect("already loaded without errors");
// after (fail soft inside the non-critical completion path)
let mut gctx = match GlobalContext::default() {
Ok(g) => g,
Err(e) => {
tracing::warn!("completion config reload failed: {e}");
return;
}
}; Defensive patterns
Strategy: try-catch
Validate before calling
// Validate that the cargo config is readable before relying on completion:
use std::process::Command;
fn cargo_config_ok() -> bool {
Command::new("cargo").arg("--version").output().map(|o| o.status.success()).unwrap_or(false)
} Try / catch
// Wrap your cargo invocation; on panic/non-zero exit from completion, fall back to no completion
let out = std::process::Command::new("cargo").args(args).status();
match out {
Ok(s) if s.success() => {}
_ => { /* silently skip completion */ }
} Prevention
- Keep `~/.cargo/config.toml` and the credentials file stable while shell completion runs.
- Ensure `HOME`/`CARGO_HOME` point to a readable directory.
- Don't run `cargo login`/`cargo logout` concurrently with shell completion.
When it happens
Trigger: Triggering tab-completion (`CARGO_COMPLETE` env) on a nightly/dev Cargo while the config files (`~/.cargo/config.toml`, `$CARGO_HOME/config.toml`, or a credential file) are concurrently modified or become unreadable; HOME unset/unwritable mid-completion; permission flip on the config between the two `GlobalContext::default()` calls.
Common situations: Shell completion triggered while a package manager or editor rewrites `~/.cargo/config.toml`; running under a sandbox/CI that mutates `$HOME`; concurrent `cargo login`/`cargo logout` rewriting the credentials file.
Related errors
- resolve should have a single spec with resolved features
- not implemented
- subcommand is required, add a subcommand to the command alia
- alias {} has unresolvable recursive definition: {} -> {}
- running the file `{cmd}` requires `-Zscript`
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/6e4d49113e7faded.json.
Report an issue: GitHub.