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.

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)

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.