gitbutlerapp/gitbutler · error

handled above

Error message

handled above

What it means

In but-forge's PR description management, `generate_footer_with_mode` is only meaningful when stacking descriptions are enabled, and the function returns `user_body` early when `all_pr_numbers.len() <= 1 || mode == ReviewStackingDescription::Disabled`. The subsequent `match mode` therefore marks `Disabled` as `unreachable!("handled above")`: the early return must have consumed that variant. The panic only fires if someone removes or reorders the early return while keeping the exhaustive match.

Solutions

  1. Preserve the early return `if all_pr_numbers.len() <= 1 || mode == Disabled { return user_body; }` ahead of the match.
  2. If reordering, give `Disabled` a real arm (`=> user_body`) instead of `unreachable!`.
  3. Add a test that calls the function with `Disabled` and multiple PR numbers to pin the guard.

Example fix

// before
match mode {
    ReviewStackingDescription::Bottom => compose_body(&user_body, &footer, ""),
    ReviewStackingDescription::Top => compose_body("", &footer, &user_body),
    ReviewStackingDescription::Disabled => unreachable!("handled above"),
}

// after
if matches!(mode, ReviewStackingDescription::Disabled) {
    return user_body; // defensive duplicate of the guard above
}
match mode {
    ReviewStackingDescription::Bottom => compose_body(&user_body, &footer, ""),
    ReviewStackingDescription::Top => compose_body("", &footer, &user_body),
    ReviewStackingDescription::Disabled => user_body,
}
Defensive patterns

Strategy: type-guard

Validate before calling

// duplicate the guard at the top of any extracted helper
if all_pr_numbers.len() <= 1 || mode == ReviewStackingDescription::Disabled {
    return user_body;
}

Type guard

fn stacking_enabled(mode: ReviewStackingDescription, pr_count: usize) -> bool {
    pr_count > 1 && !matches!(mode, ReviewStackingDescription::Disabled)
}

Prevention

When it happens

Trigger: Refactoring the early-return condition (e.g. dropping the `mode == Disabled` check) so `Disabled` reaches the match; adding a new mode variant and mishandling the guard; copy-pasting the match into a path that lacks the early return.

Common situations: Feature work on stacked-PR description modes; code motion during cleanup; tests calling the compose path directly with `Disabled` while bypassing the guard.

Related errors


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

Appendix: source

Thrown at crates/but-forge/src/review.rs:3069

                        all_pr_numbers,
                        symbol,
                        ReviewStackingDescription::Top,
                    ),
                    body,
                ),
            };
        }
    };

    if all_pr_numbers.len() <= 1 || mode == ReviewStackingDescription::Disabled {
        return user_body;
    }

    let footer = generate_footer_with_mode(pr_number, all_pr_numbers, symbol, mode);
    match mode {
        ReviewStackingDescription::Bottom => compose_body(&user_body, &footer, ""),
        ReviewStackingDescription::Top => compose_body("", &footer, &user_body),
        ReviewStackingDescription::Disabled => unreachable!("handled above"),
    }
}

enum ManagedFooter {
    Absent,
    Complete { user_body: String },
    Malformed,
}

fn strip_managed_footers(body: &str) -> ManagedFooter {
    let mut remainder = body;
    let mut user_parts = Vec::new();
    let mut found = false;

    loop {
        let top = remainder.find(STACKING_FOOTER_BOUNDARY_TOP);
        let bottom = remainder.find(STACKING_FOOTER_BOUNDARY_BOTTOM);
        match (top, bottom) {

View on GitHub (pinned to caf1f223d3)