rust-lang/cargo · critical

We've already checked that there is exactly one.

Error message

We've already checked that there is exactly one.

What it means

This is an internal invariant panic in cargo's edition-fix logic. After `resolve_differences` verifies that `ws_resolve.specs_and_features.len() == 1` (bailing otherwise at line 622-624 for the `feature-unification = "package"` case), it calls `.first().expect(...)`. The expect fires only if `specs_and_features` is somehow empty despite passing the length check, which cannot happen under normal control flow.

Source

Thrown at src/ops/cargo_fix/mod.rs:628

        let feature_opts = FeatureOpts::new_behavior(ResolveBehavior::V2, has_dev_units);
        let v2_features = FeatureResolver::resolve(
            ws,
            target_data,
            &ws_resolve.targeted_resolve,
            &ws_resolve.pkg_set,
            &opts.compile_opts.cli_features,
            &specs,
            &opts.compile_opts.build_config.requested_kinds,
            feature_opts,
        )?;

        if ws_resolve.specs_and_features.len() != 1 {
            bail!(r#"cannot fix edition when using `feature-unification = "package"`."#);
        }
        let resolved_features = &ws_resolve
            .specs_and_features
            .first()
            .expect("We've already checked that there is exactly one.")
            .resolved_features;
        let diffs = v2_features.compare_legacy(resolved_features);
        Ok((ws_resolve, diffs))
    };
    let (_, without_dev_diffs) = resolve_differences(HasDevUnits::No)?;
    let (ws_resolve, mut with_dev_diffs) = resolve_differences(HasDevUnits::Yes)?;
    if without_dev_diffs.is_empty() && with_dev_diffs.is_empty() {
        // Nothing is different, nothing to report.
        return Ok(());
    }
    // Only display unique changes with dev-dependencies.
    with_dev_diffs.retain(|k, vals| without_dev_diffs.get(k) != Some(vals));
    let gctx = ws.gctx();
    gctx.shell().note(
        "Switching to Edition 2021 will enable the use of the version 2 feature resolver in Cargo.",
    )?;
    drop_eprintln!(
        gctx,

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Report a bug at https://github.com/rust-lang/cargo/issues with the workspace manifest and exact `cargo fix` invocation; this is a cargo internal assertion, not a user-config error.
  2. Temporarily remove `feature-unification = "package"` (or the `-Z` flag enabling it) and re-run `cargo fix --edition` to confirm the panic is gated on that resolver mode.
  3. Upgrade or downgrade cargo (rustup) to a version without the regression — check the CHANGELOG for resolver/fix patches.
  4. Reproduce with `cargo fix --edition -vv` and capture the backtrace (`RUST_BACKTRACE=full`) to attach to the issue.
Defensive patterns

Strategy: validation

Validate before calling

// Before invoking edition-fix resolution, confirm the workspace resolves to exactly one spec.
let specs_count = ws_resolve.specs_and_features.len();
assert!(specs_count == 1, "expected exactly one spec, got {}", specs_count);

Prevention

When it happens

Trigger: Running `cargo fix --edition` (or `cargo fix --features` resolution diagnostics) in a workspace configured with `resolver.feature-unification = "package"` (or the equivalent unstable flag) where `WorkspaceResolve::specs_and_features` ends up empty. Concretely the `.first()` on a zero-length Vec yields `None`.

Common situations: A bug in cargo's feature resolver producing zero specs where one is expected; mixing the new `feature-unification = "package"` unstable option with edge-case workspace layouts (virtual manifests, no members resolved, exotic `[features]`); running a custom cargo build with patches to the resolve pipeline.

Related errors


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