gitbutlerapp/gitbutler · error
Could not update all PR targets before native stack…
Error message
Could not update all PR targets before native stack registration:
{} What it means
Before registering a stack natively on GitHub, the review flow updates each PR's target branch. If any of those per-PR target updates fail, the errors are collected and this bail fires listing them all, aborting before but_github::stacks::finish runs.
Solutions
- Inspect each 'PR #N target:' line to see which PRs and why they failed
- Fix the underlying cause (permissions, closed PR, API availability) and retry the push/sync
- Dissolved membership is expected here; the next successful synchronization recreates the stack, so simply retrying after fixing is safe
Defensive patterns
Strategy: try-catch
Try / catch
match result {
Err(e) if e.to_string().contains("Could not update all PR targets") => {
eprintln!("fix target-update causes and retry; membership will be recreated on next sync");
}
other => other?,
} Prevention
- Verify write access to every PR in the stack before starting registration
- Check all PRs are open before initiating the operation
- Retry after transient API failures — the next successful sync recreates the stack
When it happens
Trigger: Preparing native stack registration for a multi-PR stack where one or more PR base/target updates fail (API error, permission denied, PR closed, rate limit), collecting 'PR #N target: <err>' entries.
Common situations: Branch protection or missing write access preventing target changes; PRs force-closed by a teammate mid-operation; GitHub API 5xx or rate limiting during batch updates.
Related errors
- Could not restore native GitHub stack membership after the…
- Failed to get PR base repo
- Failed to add labels
- Failed to add to GitHub stack
- Failed to create GitHub stack
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/e985ab4e2f456910.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-forge/src/review.rs:3135
continue;
}
let params = but_github::UpdatePullRequestParams {
owner,
repo,
pr_number: review.number,
title: None,
body: None,
base: Some(target_branch),
state: None,
};
if let Err(err) = but_github::pr::update(preferred_account, params, storage).await {
target_errors.push(format!("PR #{} target: {err}", review.number));
}
}
if !target_errors.is_empty() {
// Dissolved membership stays dissolved here; the next successful synchronization sees
// no registered stacks and recreates the desired one.
anyhow::bail!(
"Could not update all PR targets before native stack registration:\n{}",
target_errors.join("\n")
);
}
but_github::stacks::finish(preferred_account, owner, repo, &prepared.plan, storage).await?;
// GitHub now renders the native stack, so GitButler's description footer is redundant.
// Strip any existing footers regardless of the configured description mode, which only
// applies to footer-based stacking. User text is preserved, and reviews whose body would
// not change are skipped entirely — unless the caller supplied a new description to push.
for (review, current_body) in reviews.iter().zip(bodies) {
let Some(current_body) = current_body else {
continue;
};
let updated_body = update_body_with_mode(
current_body.as_deref(),
review.number,View on GitHub (pinned to 58e5313667)