GitoxideLabs/gitoxide · error · anyhow::Error

extra-header-lookup is only meaningful in threaded mode

Error message

extra-header-lookup is only meaningful in threaded mode

What it means

In `gix repo odb statistics`, the `extra-header-lookup` option only applies when object lookups run on multiple threads. In single-threaded mode the option has no effect, so the command rejects it explicitly rather than silently ignoring it.

Solutions

  1. Enable the threaded mode (pass the threads option) so extra-header-lookup takes effect.
  2. Remove `--extra-header-lookup` when running single-threaded.
  3. If throughput is not the goal, drop the flag — it only matters for pack multi-threaded statistics.

Example fix

// before (single-threaded)
gix repo odb statistics --extra-header-lookup <pack>
// after
gix repo odb statistics --threads 4 --extra-header-lookup <pack>
Defensive patterns

Strategy: validation

Validate before calling

if extra_header_lookup && threads == 0 { // 0 = single-threaded
    eprintln!("dropping --extra-header-lookup: only meaningful threaded");
    extra_header_lookup = false;
}

Try / catch

match odb_statistics(...) {
    Err(e) if e.to_string().contains("extra-header-lookup") => retry_without_flag(),
    r => r?,
}

Prevention

When it happens

Trigger: Running odb statistics without the threaded/threads option (single-threaded path in `statistics()`) while passing `extra_header_lookup == true`.

Common situations: Copying a threaded benchmark invocation into an environment where threading was disabled; passing a flag intended for a different mode of the same command.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at gitoxide-core/src/repository/odb.rs:209

            |ids, (handle, counter)| {
                let ids = ids?;
                counter.fetch_add(ids.len(), Ordering::Relaxed);
                let out = ids
                    .into_iter()
                    .map(|id| handle.header(id).map(|hdr| (id, hdr)))
                    .collect::<Result<Vec<_>, _>>()?;
                Ok(out)
            },
            Reduce {
                stats: Statistics {
                    ids: extra_header_lookup.then(Vec::new),
                    ..Default::default()
                },
            },
        )?
    } else {
        if extra_header_lookup {
            bail!("extra-header-lookup is only meaningful in threaded mode");
        }
        let mut stats = Statistics::default();

        for (count, id) in object_ids.enumerate() {
            if count % chunk_size == 0 && gix::interrupt::is_triggered() {
                return Err(cancelled());
            }
            stats.consume(repo.objects.header(id)?);
            progress.inc();
        }
        stats
    };

    progress.show_throughput(start);

    if let Some(mut ids) = stats.ids.take() {
        // Critical to re-open the repo to assure we don't have any ODB state and start fresh.
        let start = std::time::Instant::now();

View on GitHub (pinned to e73179060b)