GitoxideLabs/gitoxide · error

valid enrich ref

Error message

valid enrich ref

What it means

Panic from converting the hard-coded constant `crate::enrich::REF_NAME` into a `gix::refs::FullName` with `.expect("valid enrich ref")`. The name is a compile-time constant like `refs/tix/enrich`, so conversion failure would mean the shipped constant is malformed — an internal invariant guaranteed by the library authors, never caused by user input.

Solutions

  1. If you maintain a fork, ensure `crate::enrich::REF_NAME` is a fully qualified name such as `refs/tix/enrich`.
  2. Restore the original constant if it was customized.
  3. Report upstream if stock builds panic here.

Example fix

// before
pub const REF_NAME: &str = "tix/enrich"; // invalid: not fully qualified
// after
pub const REF_NAME: &str = "refs/tix/enrich";
Defensive patterns

Strategy: validation

Validate before calling

gix::refs::FullName::try_from(crate::enrich::REF_NAME)
    .map_err(|e| anyhow::anyhow!("enrich ref name invalid: {e}"))?;

Type guard

fn valid_enrich_ref(name: &str) -> bool {
    gix::refs::FullName::try_from(name.to_owned()).is_ok() && name.starts_with("refs/")
}

Prevention

When it happens

Trigger: Any call path into `enrichment_edits` (writing enrichment data during rebase/stash rewrite); the panic fires only if the constant REF_NAME in the crate is not a valid fully-qualified reference name.

Common situations: Only reachable in modified or forked builds where `REF_NAME` was edited to a non-fully-qualified name (e.g. missing the `refs/` prefix).

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/eaac40f8b60530dc. Report an issue: GitHub.

Appendix: source

Thrown at gix-tix/src/edit/rebase.rs:2358

    let mut time = gix::date::parse::TimeBuf::default();
    let actor = committer.to_ref(&mut time);
    let commit = repo
        .new_commit_as(actor, actor, "Notes copied by tix", root, parent)
        .context("could not prepare the rewritten Git notes commit")?
        .id;
    Ok(super::stash::RewriteEdits {
        forward: vec![ref_edit(name.clone(), parent, Some(commit))],
        rollback: vec![ref_edit(name, Some(commit), parent)],
    })
}

fn enrichment_edits(
    repo: &gix::Repository,
    object: ObjectId,
    data: BString,
    committer: &gix::actor::Signature,
) -> Result<super::stash::RewriteEdits> {
    let name: gix::refs::FullName = crate::enrich::REF_NAME.try_into().expect("valid enrich ref");
    let (root, parent) = match repo.try_find_reference(name.as_ref())? {
        Some(mut reference) => {
            let parent = reference
                .try_id()
                .context("the tix enrich reference must be direct")?
                .detach();
            let root = reference
                .peel_to_tree()
                .context("could not read the tix enrich tree")?
                .id;
            (root, Some(parent))
        }
        None => (ObjectId::empty_tree(repo.object_hash()), None),
    };
    let note = repo.write_blob(data)?.detach();
    let mut state = gix::note::plumbing::State::new(root, repo)
        .map_err(gix::Exn::into_error)
        .context("could not initialize the tix enrichment tree")?;

View on GitHub (pinned to e73179060b)