rust-lang/cargo · error · anyhow::Error

the manifest file needs to be updated but was passed to…

Error message

the manifest file {} needs to be updated but {locked_flag} was passed to prevent this

What it means

Thrown by cargo add when the --locked flag is active and the operation would change the Cargo.toml manifest. The --locked flag asserts that no files should be modified beyond what the lockfile expects; cargo add inherently writes to the manifest, creating a conflict.

Solutions

  1. Remove the --locked flag from the cargo add invocation
  2. Unset the CARGO_LOCKED environment variable: `unset CARGO_LOCKED`
  3. If you need reproducibility, run cargo add without --locked first, commit the manifest change, then use --locked for subsequent build/test commands

Example fix

# before
cargo add serde --locked
# error: the manifest file Cargo.toml needs to be updated

# after — remove --locked for add operations
cargo add serde
Defensive patterns

Strategy: validation

Validate before calling

// Detect --locked before running cargo add
fn should_use_locked(add_command: &str) -> bool {
    // cargo add inherently modifies the manifest, so --locked is incompatible
    if add_command.contains("--locked") {
        eprintln!("warning: --locked prevents cargo add from writing; removing it");
        return false;
    }
    false
}

Prevention

When it happens

Trigger: Running `cargo add <dep> --locked` (or with the CARGO_LOCKED environment variable set) in a context where the dependency addition changes the manifest content.

Common situations: CI pipelines that pass --locked to all cargo commands. Scripts that set CARGO_LOCKED globally. Using --locked out of habit without realizing cargo add must write.

Related errors


AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11). Data as JSON: /api/errors/824ba8ea63d57b08. Report an issue: GitHub.

Appendix: source

Thrown at src/ops/cargo_add/mod.rs:290

        }
        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 98a09e7e7d)