gitbutlerapp/gitbutler · error · anyhow::Error

Failed to find reference {ref_name} due to it being dropped

Error message

Failed to find reference {ref_name} due to it being dropped in the traversal overlay

What it means

Thrown by TraversalOverlay::find_reference (crates/but-graph/src/init/overlay.rs:200) when asked for a ref that the overlay has explicitly dropped. The traversal overlay hides refs (e.g., refs consumed by the workspace/virtual branches) so the graph sees a curated refdb; lookups of dropped refs deliberately fail fast instead of returning None or leaking the underlying repo's ref — silently succeeding would break the overlay's invariants. Overriding refs are served from the overlay map, non-overriding ones from nonoverriding_references, and only then does it fall through to the inner repository.

Source

Thrown at crates/but-graph/src/init/overlay.rs:200

        if self.dropped_references.contains(ref_name) {
            Ok(None)
        } else if let Some(r) = self.overriding_references.get(ref_name) {
            Ok(Some(r.clone().attach(self.inner)))
        } else if let Some(rn) = self.inner.try_find_reference(ref_name)? {
            Ok(Some(rn))
        } else if let Some(r) = self.nonoverriding_references.get(ref_name) {
            Ok(Some(r.clone().attach(self.inner)))
        } else {
            Ok(None)
        }
    }

    pub fn find_reference(
        &self,
        ref_name: &gix::refs::FullNameRef,
    ) -> anyhow::Result<gix::Reference<'repo>> {
        if self.dropped_references.contains(ref_name) {
            bail!(
                "Failed to find reference {ref_name} due to it being dropped in the traversal overlay"
            );
        }
        if let Some(r) = self.overriding_references.get(ref_name) {
            return Ok(r.clone().attach(self.inner));
        }
        Ok(self
            .inner
            .find_reference(ref_name)
            .or_else(|err| match err {
                gix::reference::find::existing::Error::Find(_) => Err(err),
                gix::reference::find::existing::Error::NotFound { .. } => {
                    if let Some(r) = self.nonoverriding_references.get(ref_name) {
                        Ok(r.clone().attach(self.inner))
                    } else {
                        Err(err)
                    }
                }

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Do not resolve refs you know the workspace manages — check membership in the dropped set (or your own record of dropped refs) before lookup
  2. Use the Option-returning lookup path (the one consulting nonoverriding_references and returning Ok(None)) when 'dropped' and 'missing' should both mean absent
  3. If you genuinely need the physical ref, query the inner repository directly, understanding it bypasses overlay semantics

Example fix

// before
let reference = overlay.find_reference(&ref_name)?; // bails for workspace-dropped refs

// after: treat 'dropped by overlay' as not-found
let reference = match overlay.find_reference(&ref_name) {
    Ok(r) => Some(r),
    Err(err) if err.to_string().contains("dropped in the traversal overlay") => None,
    Err(err) => return Err(err),
};
Defensive patterns

Strategy: fallback

Try / catch

let reference = match overlay.find_reference(&ref_name) {
    Ok(r) => Some(r),
    Err(err) if err.to_string().contains("dropped in the traversal overlay") => {
        None // dropped and missing both mean 'not present' in the overlay view
    }
    Err(err) => return Err(err),
};

Prevention

When it happens

Trigger: Calling overlay.find_reference() for a branch whose commits are absorbed into the GitButler workspace (its ref was dropped from the overlay); looking up a ref that init decided to hide during traversal setup; code that mixes overlay lookups with raw-repo assumptions querying a hidden ref.

Common situations: Workspace code that assumes all repo refs remain visible under the overlay; tests constructing an overlay with dropped refs and then querying them; tooling that enumerates refs before init and resolves them after init dropped some.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/ae53bd1cf73559cb. Report an issue: GitHub.