rust-lang/cargo · error
the manifest file {} needs to be updated but {locked_flag} w
Error message
the manifest file {} needs to be updated but {locked_flag} was passed to prevent this What it means
When `--locked` (or the equivalent `locked_flag`) is in effect, cargo-add refuses to modify `Cargo.toml` even though adding the dependency requires writing to it. The function snapshots the raw manifest before processing, applies edits in memory, and if `original_raw_manifest != new_raw_manifest` under a locked flag it bails. This guarantees reproducible, frozen manifests in CI.
Source
Thrown at src/ops/cargo_add/mod.rs:288
}
manifest.gc_dep(dep.toml_key());
}
if was_sorted {
if let Some(table) = manifest
.get_table_mut(&dep_table)
.and_then(TomlItem::as_table_like_mut)
{
table.sort_values();
}
}
manifest.ensure_edition();
if let Some(locked_flag) = options.gctx.locked_flag() {
let new_raw_manifest = manifest.to_string();
if original_raw_manifest != new_raw_manifest {
anyhow::bail!(
"the manifest file {} needs to be updated but {locked_flag} was passed to prevent this",
manifest.path.display()
);
}
}
if options.dry_run {
options.gctx.shell().warn("aborting add due to dry run")?;
} else {
manifest.write()?;
}
Ok(())
}
/// Dependency entry operation
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct DepOp {View on GitHub (pinned to 0e07a15537)
Solutions
- Drop `--locked` from the `cargo add` invocation; adding a dependency is inherently a manifest mutation.
- If reproducibility is required, run `cargo add` without `--locked`, commit the new `Cargo.toml` and `Cargo.lock`, and keep `--locked` for subsequent `cargo build`/`cargo generate-lockfile` steps.
- Audit `.cargo/config.toml` and your CI matrix for a global `locked = true` or wrapper that injects `--locked`.
Example fix
# before (CI) cargo add serde --locked # after cargo add serde git commit -am "add serde"
Defensive patterns
Strategy: validation
Validate before calling
// Never pass --locked to an additive operation. Strip it before invoking cargo add.
fn sanitize_add_args(args: &mut Vec<String>) {
if args.iter().any(|a| a == "add") {
args.retain(|a| a != "--locked");
}
} Prevention
- Keep `--locked` scoped to read/lock operations (`build`, `generate-lockfile`), not `add`.
- In CI, separate the dependency-bootstrap step from the locked-build step.
- Document in your Makefile which targets are lock-affecting vs lock-consuming.
When it happens
Trigger: Running `cargo add <dep> --locked`, or any `cargo add` invocation while `.cargo/config.toml` / environment forces locked mode. Any dependency addition mutates the manifest, so the diff is always non-empty and the bail fires.
Common situations: CI pipelines that pass `--locked` globally to all cargo subcommands, or Dockerfile lines that bake `--locked` into a generic cargo wrapper. The flag is meaningful for `build`/`update` but conflicts with an *additive* manifest operation.
Related errors
- Deprecated dependency sections are unsupported: {}
- cannot {action} the lock file {lockfile_path} because {locke
- manifest validated
- dependency `{}` in package `{}` requires a `{}` artifact to
- multiple packages link to native library `{}`, but a native
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/824ba8ea63d57b08.json.
Report an issue: GitHub.