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

cannot specify both recursive and precise simultaneously

Error message

cannot specify both recursive and precise simultaneously

What it means

In update_lockfile, `--recursive` (walk transitive deps) and `--precise <version>` (pin one version) have conflicting semantics, so cargo_update.rs:62 rejects using both at once.

Source

Thrown at src/ops/cargo_update.rs:62

    let previous_resolve = None;
    let mut resolve = ops::resolve_with_previous(
        &mut registry,
        ws,
        &CliFeatures::new_all(true),
        HasDevUnits::Yes,
        previous_resolve,
        None,
        &[],
        true,
    )?;
    ops::write_pkg_lockfile(ws, &mut resolve)?;
    print_lockfile_changes(ws, previous_resolve, &resolve, &mut registry)?;
    Ok(())
}

pub fn update_lockfile(ws: &Workspace<'_>, opts: &UpdateOptions<'_>) -> CargoResult<()> {
    if opts.recursive && opts.precise.is_some() {
        anyhow::bail!("cannot specify both recursive and precise simultaneously")
    }

    if ws.members().count() == 0 {
        anyhow::bail!("you can't generate a lockfile for an empty workspace.")
    }

    // Updates often require a lot of modifications to the registry, so ensure
    // that we're synchronized against other Cargos.
    let _lock = ws
        .gctx()
        .acquire_package_cache_lock(CacheLockMode::DownloadExclusive)?;

    let previous_resolve = match ops::load_pkg_lockfile(ws)? {
        Some(resolve) => resolve,
        None => {
            match opts.precise {
                None => return generate_lockfile(ws),

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Drop one of the flags: use `--precise <ver>` alone to pin, or `--recursive` alone to walk deps.
  2. If you want to pin several deps, call `cargo update --precise` once per package rather than combining with --recursive.

Example fix

# before
$ cargo update --recursive -p serde --precise 1.0.150
error: cannot specify both recursive and precise simultaneously

# after - choose one
$ cargo update -p serde --precise 1.0.150
#   or
$ cargo update --recursive -p serde
Defensive patterns

Strategy: validation

Validate before calling

# Reject combining --recursive with --precise on cargo update:
for a in "$@"; do
  case "$a" in --recursive) rec=1;; --precise) prec=1;; esac
done
if [ "$rec" = 1 ] && [ "$prec" = 1 ]; then
  echo "--recursive and --precise are mutually exclusive" >&2; exit 1
fi
cargo update "$@"

Prevention

When it happens

Trigger: Passing both `--recursive` and `--precise <ver>` to `cargo update`.

Common situations: Misreading the update docs; combining flags copied from examples; scripting a one-off that accidentally sets both.

Related errors


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