rust-lang/cargo · critical

at least one iteration

Error message

at least one iteration

What it means

Invariant panic in `fix_warnings`: after the iterate-until-converged loop, the code does `first_output.expect("at least one iteration")`. The loop is a bare `loop { ... }` that always executes its body once and sets `first_output = Some(...)` when `current_iteration == 0` (line 930-932). So the Option is always Some unless the loop body is refactored to skip the assignment.

Source

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

        debug!("calling rustc one last time for final results: {rustc}");
        last_output = rustc.output()?;
    }

    // Any errors still remaining at this point need to be reported as probably
    // bugs in Cargo and/or rustfix.
    for (path, file) in files.iter_mut() {
        for error in file.errors_applying_fixes.drain(..) {
            Message::ReplaceFailed {
                file: path.clone(),
                message: error,
            }
            .post(gctx)?;
        }
    }

    Ok(FixedCrate {
        files,
        first_output: first_output.expect("at least one iteration"),
        last_output,
    })
}

/// Executes `rustc` to apply one round of suggestions to the crate in question.
///
/// This will fill in the `fixes` map with original code, suggestions applied,
/// and any errors encountered while fixing files.
fn rustfix_and_fix(
    files: &mut HashMap<String, FixedFile>,
    rustc: &ProcessBuilder,
    filename: &Path,
    args: &FixArgs,
    gctx: &GlobalContext,
) -> CargoResult<(Output, bool)> {
    // If not empty, filter by these lints.
    // TODO: implement a way to specify this.
    let only = HashSet::default();

View on GitHub (pinned to 0e07a15537)

Solutions

  1. If you hit this in released cargo, file a cargo bug — it indicates a regression in the fix loop.
  2. If you are editing cargo source, ensure the loop body runs at least once before any `break`/`return`, or initialize `first_output` before the loop.
  3. Reproduce with `RUST_BACKTRACE=1 cargo fix ...` and capture the trace for the bug report.

Example fix

// before
let mut first_output = None;
loop {
    // ...
    if current_iteration == 0 { first_output = Some(last_output.clone()); }
    // ...
}
first_output.expect("at least one iteration")

// after (defensive: run rustc once before the loop)
let mut first_output = Some(rustc.output()?.clone());
loop { /* ... */ }
Defensive patterns

Strategy: validation

Validate before calling

// N/A for callers — this is an internal loop invariant. No public API pre-check helps.

Prevention

When it happens

Trigger: Triggered only if `cargo fix`'s apply-loop exits with `first_output` still `None`. The loop unconditionally runs the body at least once, so under the shipped code this is unreachable; a future refactor that short-circuits before iteration 0 could expose it.

Common situations: Effectively not user-reachable in released cargo. Encountered only by cargo contributors editing `fix_warnings`/`rustfix_and_fix` and accidentally bypassing the `current_iteration == 0` assignment.

Related errors


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