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
- Preserve the early return `if all_pr_numbers.len() <= 1 || mode == Disabled { return user_body; }` ahead of the match.
- If reordering, give `Disabled` a real arm (`=> user_body`) instead of `unreachable!`.
- 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
- Keep the early-return guard and the mode match adjacent in the same function.
- Give Disabled a benign arm instead of unreachable! when refactoring the guard.
- Add a test with mode=Disabled and multiple PR numbers to pin the ordering.
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
- handled above
- BUG: {id} is queued
- candidate turns always have review or branch evidence
- validated AI responses only produce content picks
- we never return these as the status iteration is configured
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/1d1ef58686e9db88.
Report an issue: GitHub.