gitbutlerapp/gitbutler · info

known to be valid statically

Error message

known to be valid statically

What it means

When converting GitbutlerBranch into a listing, segments without a RefInfo get a fake ref name "refs/heads/unnamed-ref-and-we-fake-a-name-fix-me", whose literal string is expect()'d to be a valid gix::refs::FullName. The panic is statically impossible because the string is a hardcoded valid ref name — it documents an intentional placeholder for stack segments that have no real ref yet.

Solutions

  1. No action needed for the panic itself — it is statically unreachable
  2. Model the segment tip as Option<gix::refs::FullName> so no fake name is fabricated (remove the placeholder, marked fix-me)
  3. Handle segments without ref_info explicitly in the UI instead of inventing a name

Example fix

// before
tip: s.ref_info.clone().map(|ri| ri.ref_name).unwrap_or_else(|| {
    gix::refs::FullName::try_from("refs/heads/unnamed-ref-and-we-fake-a-name-fix-me")
        .expect("known to be valid statically")
}),
// after
tip: s.ref_info.clone().map(|ri| ri.ref_name),
Defensive patterns

Strategy: type-guard

Validate before calling

// No runtime guard needed: the panic is statically unreachable (literal valid ref name).
// Guard the data instead: check segments have ref_info before rendering tips.
let tip = segment.ref_info.as_ref().map(|ri| ri.ref_name);

Type guard

fn segment_has_tip(segment: &GitbutlerStackEntry) -> bool {
    segment.ref_info.is_some()
}

Prevention

When it happens

Trigger: Rendering branch/stack details where a GitbutlerStackEntry segment has no ref_info (e.g. an integration/pending segment with no resolved ref), so the fallback fake name is constructed. The expect itself never fires.

Common situations: Listing branches in the UI while a stack contains an unassigned or uncommitted-change segment that has no underlying git ref; serialized/partial branch data missing ref_info.

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 gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/75db3b1fa7e45b08. Report an issue: GitHub.

Appendix: source

Thrown at crates/gitbutler-branch-actions/src/branch.rs:468

                        )
                    })
                })
                .transpose()?,
            updated_timestamp_ms: first_segment
                .and_then(|s| {
                    let md = s.metadata.as_ref()?;
                    Some(md.ref_info.updated_at?.seconds as u128 * 1_000)
                })
                .unwrap_or_default(),
            unarchived_segments: stack
                .segments
                .iter()
                .map(|s| GitbutlerStackSegment {
                    tip: s.ref_info.clone().map(|ri| ri.ref_name).unwrap_or_else(|| {
                        gix::refs::FullName::try_from(
                            "refs/heads/unnamed-ref-and-we-fake-a-name-fix-me",
                        )
                        .expect("known to be valid statically")
                    }),
                    pr_or_mr: s
                        .remote_tracking_ref_name
                        .as_ref()
                        .and_then(|rn| extract_remote_name_and_short_name(rn.as_ref(), names))
                        .and_then(|(_, short)| reviews_by_head.get(short.to_str().ok()?))
                        .and_then(|review| usize::try_from(review.number).ok()),
                })
                .collect(),
        }))
    }
}

impl GitButlerStack {
    /// Return the top-most stack's commit id.
    fn head_oid<'repo>(&self, repo: &'repo gix::Repository) -> anyhow::Result<gix::Id<'repo>> {
        let tip_ref = self
            .unarchived_segments

View on GitHub (pinned to 58e5313667)