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
- If you hit this in released cargo, file a cargo bug — it indicates a regression in the fix loop.
- 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.
- 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
- Use released cargo toolchains for `cargo fix` rather than custom builds.
- If patching cargo, initialize `first_output` before the loop or assert the loop runs once.
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
- artifact-dir was not locked
- artifact dep
- already loaded config values
- env var was not array
- was not filled at beginning of the function
AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06).
Data as JSON: /data/errors/75803b5da6a10bbe.json.
Report an issue: GitHub.