GitoxideLabs/gitoxide · error

successful iteration has outcome

Error message

successful iteration has outcome

What it means

After a status iteration completes successfully, `iter.outcome_mut()` is expected to hold the computed outcome. The `.expect()` panics if iteration reported success but no outcome was stored, indicating a bug in gix's status machinery rather than a user error.

Solutions

  1. Update gix/gitoxide to the latest version to pick up fixed outcome-propagation bugs.
  2. Ensure the status iteration runs to completion before requesting `outcome_mut()` (propagate the iteration Result).
  3. Handle `None` gracefully in the CLI (bail with a message) instead of panicking.

Example fix

// before
let out = iter.outcome_mut().expect("successful iteration has outcome");

// after
let Some(out) = iter.outcome_mut() else {
    bail!("status iteration produced no outcome");
};
Defensive patterns

Strategy: try-catch

Try / catch

let Some(out) = iter.outcome_mut() else {
    bail!("status iteration produced no outcome despite success");
};

Prevention

When it happens

Trigger: Calling the `show` status path where `iter` finished without error but `outcome_mut()` returned `None` (e.g. iteration never ran to completion internally).

Common situations: Interrupted status computation that nonetheless reported success; gix version mismatch where the outcome type changed; a genuine library bug surfacing in the CLI.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/a8333248810e923a. Report an issue: GitHub.

Appendix: source

Thrown at gitoxide-core/src/repository/status.rs:202

                    out,
                    "{status: >3} {source_rela_path} → {dest_rela_path}",
                    status = "R",
                    source_rela_path =
                        gix::path::relativize_with_prefix(&gix::path::from_bstr(source.rela_path()), prefix).display(),
                    dest_rela_path = gix::path::relativize_with_prefix(
                        &gix::path::from_bstr(dirwalk_entry.rela_path.as_bstr()),
                        prefix
                    )
                    .display(),
                )?;
            }
        }
    }
    if gix::interrupt::is_triggered() {
        bail!("interrupted by user");
    }

    let out = iter.outcome_mut().expect("successful iteration has outcome");

    if out.has_changes() && allow_write {
        out.write_changes().transpose()?;
    }

    if statistics {
        writeln!(err, "{outcome:#?}", outcome = out.index_worktree).ok();
    }

    progress.init(Some(out.worktree_index.entries().len()), gix::progress::count("files"));
    progress.set(out.worktree_index.entries().len());
    progress.show_throughput(start);
    Ok(())
}

fn print_index_entry_status(
    out: &mut dyn std::io::Write,
    prefix: &Path,

View on GitHub (pinned to e73179060b)