gitbutlerapp/gitbutler · error
Could not restore all review targets after the push failed:
Error message
Could not restore all review targets after the push failed:
{} What it means
When a stack push fails, GitButler rewinds local branch refs back to the reviewed targets they had before the push. If any of those restore updates also fail, the accumulated per-branch errors are reported together; dissolved native GitHub stack memberships are additionally noted as not restored (the next successful push recreates them).
Source
Thrown at crates/but-api/src/legacy/forge.rs:1547
Some(review.target_branch.clone()),
)
.await
{
errors.push(format!(
"Failed to restore review #{} to `{}`: {err}",
review.number, review.target_branch
));
}
}
if !errors.is_empty() {
if !flattening.dissolved_stacks.is_empty() {
errors.push(
"Native GitHub stack membership was not restored; the next successful push will \
recreate it."
.to_string(),
);
}
anyhow::bail!(
"Could not restore all review targets after the push failed:\n{}",
errors.join("\n")
)
}
if flattening.dissolved_stacks.is_empty() {
return Ok(());
}
let (storage, forge_repo_info, preferred_forge_user) = {
let ctx = ctx.into_thread_local();
let project_meta = ctx.project_meta()?;
let repo = ctx.repo.get()?;
let (forge_repo_info, _) = base_and_push_repo_info(&project_meta, &repo)?;
(
but_forge_storage::Controller::from_path(but_path::app_data_dir()?),
forge_repo_info,
ctx.legacy_project.preferred_forge_user.clone(),
)View on GitHub (pinned to 2497b8007a)
Solutions
- Read the per-branch list in the message and reset those branches to their reviewed targets via the stacks UI or oplog undo
- Stop competing git processes on the project, then retry the push — a successful push also recreates dissolved GitHub stack memberships
- Run git fsck if objects are missing; restore from a healthy clone if needed
- If branches refuse to reset, use undo to return the workspace to a consistent snapshot
Defensive patterns
Strategy: try-catch
Validate before calling
// After any failed push, verify branches with reviews are back on their reviewed tips
for branch in branches_with_reviews {
let reviewed = reviewed_target_oid(branch)?;
ensure_local_ref_matches(ctx, branch, reviewed)?; // surface drift to the user early
} Try / catch
match push_stack_with_reviews(ctx, stack).await {
Err(err) if err.to_string().contains("Could not restore all review targets") => {
// parse the branch list from the message, show a repair dialog,
// offer undo or stacks-UI reset to reviewed targets
}
other => other,
} Prevention
- Run one GitButler instance per project
- Retry failed pushes promptly so local and remote states re-converge
- After any failed push, check the stacks view for branches stuck between reviewed targets
When it happens
Trigger: A push (or local target ref update) failed, and during rollback some branches could not be reset to their reviewed commits — refs locked by another process, missing objects, or concurrent ref updates.
Common situations: Another git process (IDE, hook, second GitButler instance) holds refs while the push fails; the remote changed concurrently; partially missing object store after disk issues.
Related errors
- Branch `{}` is pushed, but its remote ancestry does not matc
- No HEAD reference found for remote {remote_name}
- Branch {branch_name} not found
- Target branch {target_ref_name} not found
- PR template exists but must be valid UTF-8 text or markdown
AI-assisted analysis of gitbutlerapp/gitbutler@2497b8007a (2026-08-17).
Data as JSON: /api/errors/480fa3d3c3ba66a6.
Report an issue: GitHub.