gitbutlerapp/gitbutler · warning
target OID must exist when merge check is enabled
Error message
target OID must exist when merge check is enabled
What it means
Defensive expect in 'but branch list': the merge-status check (default on; disabled with --no-check) needs the workspace target's commit id to test whether branches merge cleanly into it. As with the ahead calculation, target_oid is resolved whenever '!empty || ahead || check_merge' holds and resolution failures propagate as errors before this point, so the expect is a wiring invariant rather than a reachable user-facing failure.
Source
Thrown at crates/but/src/command/legacy/branch/list.rs:205
let has_more_branches = branches_to_show.len() > max_branches;
let branches_to_show: Vec<_> = branches_to_show.into_iter().take(max_branches).collect();
// Calculate commits ahead if requested
let commits_ahead_map: Option<HashMap<String, usize>> = if ahead {
Some(calculate_commits_ahead(
ctx,
target_oid.expect("target OID must exist when ahead calculation is enabled"),
&branches_to_show,
)?)
} else {
None
};
// Check merge status if requested
let merge_status_map: Option<HashMap<String, bool>> = if check_merge {
Some(check_branches_merge_cleanly(
ctx,
target_oid.expect("target OID must exist when merge check is enabled"),
&applied_stacks,
&branches_to_show,
)?)
} else {
None
};
let allow_truncation = out.format().allows_truncation();
if let Some(out) = out.for_json() {
output_json(
&applied_stacks,
&branches_to_show,
has_more_branches,
&branch_review_map,
commits_ahead_map.as_ref(),
merge_status_map.as_ref(),
ctx,
out,View on GitHub (pinned to 2497b8007a)
Solutions
- Update the resolution condition whenever a new flag consumes target_oid
- Maintainer: convert to an ok_or_else error naming --check as the requiring flag
- Cover the flag matrix (--no-check, --no-ahead, --empty) in CLI tests
Example fix
// before
target_oid.expect("target OID must exist when merge check is enabled")
// after
let target_oid = target_oid.ok_or_else(|| {
anyhow::anyhow!("merge checking needs a resolvable workspace target branch; fetch the target ref first")
})?; Defensive patterns
Strategy: validation
Validate before calling
// Ensure sync of the merge-check consumer with target resolution // (unit-level: invoke the list handler with check_merge=true and a resolvable workspace) let out = run_but(&["branch", "list"]).assert().success(); let out_no_check = run_but(&["branch", "list", "--no-check"]).assert().success();
Prevention
- Treat '--no-check' as the immediate workaround when target resolution errors (not panics) appear
- Keep the flag list that requires the target documented next to the resolution condition
- Convert sibling expects to ok_or_else errors when touching this file
When it happens
Trigger: Only a refactor that enables check_merge handling while resolving target_oid under a narrower condition than list.rs:47 uses; user input alone cannot trigger it.
Common situations: Contributors changing flag semantics around target resolution; end users instead hit the propagated 'target unresolved' error when the workspace base branch is missing.
Related errors
- target OID must exist when ahead calculation is enabled
- non-empty conflicts map contains a commit
- object for prefix exists
- WithSyntaxHighlighting ensures the line is highlighted
- classified branches are guaranteed to be non-empty
AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17).
Data as JSON: /api/errors/af0a8b4d957751b9.
Report an issue: GitHub.