GitoxideLabs/gitoxide · error · anyhow::Error

Unknown extension , expecting 'idx' or 'pack

Error message

Unknown extension {ext:?}, expecting 'idx' or 'pack'

What it means

Thrown by `pack_or_pack_index` in the pack verify path when the file extension exists but is neither `idx` nor `pack`. The verify command only understands those two pack-related formats and refuses any other extension explicitly.

Solutions

  1. Verify the actual `.pack` or `.idx` file instead of companion files like `.midx`, `.bitmap`, `.keep`, or `.rev`
  2. Check `ls .git/objects/pack/` and pick the `pack-*.pack` (or its `.idx`) file
  3. Use `git multi-pack-index verify` for `.midx` files, which gix pack verify does not handle

Example fix

// before
gix pack verify .git/objects/pack/multi-pack-index
// after
gix pack verify .git/objects/pack/pack-abc123.pack
Defensive patterns

Strategy: validation

Validate before calling

match path.extension().and_then(|e| e.to_str()) {
    Some("idx") | Some("pack") => Ok(()),
    Some(ext) => Err(format!("unsupported companion file .{ext}; use the .pack/.idx instead")),
    None => Err("no extension".into()),
}?

Type guard

fn is_verifiable_pack(p: &std::path::Path) -> bool {
    matches!(p.extension().and_then(|e| e.to_str()), Some("idx") | Some("pack"))
}

Prevention

When it happens

Trigger: Running `gix pack verify file.midx`, `file.tar`, `file.keep`, or any file whose extension is not exactly `idx` or `pack`.

Common situations: Users try to verify multi-pack-index (`.midx`) or `.keep`/`.bitmap`/`.rev` companion files that git also stores in the pack directory, assuming they are verifiable packs.

Related errors


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

Appendix: source

Thrown at gitoxide-core/src/pack/verify.rs:199

                        out,
                        &multi_index
                            .index_names()
                            .iter()
                            .zip(res.pack_traverse_statistics)
                            .collect::<Vec<_>>(),
                    )?,
                    _ => {}
                }
                return Ok(());
            }
            _ => {
                return Err(anyhow!(
                    "Cannot determine data type on path without extension '{}', expecting default extensions 'idx' and 'pack'",
                    path.display()
                ));
            }
        },
        ext => return Err(anyhow!("Unknown extension {ext:?}, expecting 'idx' or 'pack'")),
    };
    if let Some(stats) = res.1.as_ref() {
        #[cfg_attr(not(feature = "serde"), allow(clippy::single_match))]
        match output_statistics {
            Some(OutputFormat::Human) => drop(print_statistics(&mut out, stats)),
            #[cfg(feature = "serde")]
            Some(OutputFormat::Json) => serde_json::to_writer_pretty(out, stats)?,
            _ => {}
        }
    }
    Ok(())
}

fn print_statistics(out: &mut impl io::Write, stats: &index::traverse::Statistics) -> io::Result<()> {
    writeln!(out, "objects per delta chain length")?;
    let mut chain_length_to_object: Vec<_> = stats.objects_per_chain_length.iter().map(|(a, b)| (*a, *b)).collect();
    chain_length_to_object.sort_by_key(|e| e.0);
    let mut total_object_count = 0;

View on GitHub (pinned to e73179060b)