gitbutlerapp/gitbutler · error
Could not restore native GitHub stack membership after the…
Error message
Could not restore native GitHub stack membership after the push failed:
{} What it means
After a failed push, the GitHub review code attempts to restore each PR's native stack membership (re-registering PRs into their stacks). Any error from those restore steps is collected; if any occurred, this error bails listing all of them. It indicates cleanup-after-failure also failed, so local and GitHub stack state may be inconsistent.
Solutions
- Read the per-error lines in the message to identify which PRs failed to restore
- Re-run the stack synchronization (but push / sync) once the API is reachable; the next successful sync recreates the desired stacks
- Check the GitHub token's scopes and repo access for the failing PRs
Defensive patterns
Strategy: try-catch
Try / catch
match push_result {
Err(e) if e.to_string().contains("Could not restore native GitHub stack membership") => {
log::error!("push failed AND membership restore failed; state may be inconsistent: {e:#}");
// schedule a re-sync
}
other => other?,
} Prevention
- Ensure the token has rights to update all PRs in the stack before pushing
- Monitor GitHub API health/rate limits around push operations
- Re-run synchronization after this error to restore consistent state
When it happens
Trigger: A push of a stacked-review branch fails, then the restore_native_stack_membership routine errors on one or more PRs (API failures, permission problems, deleted PRs), producing this aggregated bail.
Common situations: GitHub API outages or rate limits during push failure recovery; token lacking rights to update the PRs; PRs closed/deleted concurrently so membership cannot be re-registered.
Related errors
- Could not update all PR targets before native stack…
- Could not restore all review targets after the push failed
- 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/0e9f6126332f46c1.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-forge/src/review.rs:2971
preferred_forge_user: &Option<crate::ForgeUser>,
forge_repo_info: &crate::forge::ForgeRepoInfo,
stacks: &[Vec<i64>],
storage: &but_forge_storage::Controller,
) -> Result<()> {
let crate::forge::ForgeRepoInfo { owner, repo, .. } = forge_repo_info;
let preferred_account = preferred_forge_user.as_ref().and_then(|user| user.github());
let mut errors = Vec::new();
for pull_requests in stacks {
if let Err(err) =
but_github::stacks::create(preferred_account, owner, repo, pull_requests, storage).await
{
errors.push(format!("{err:#}"));
}
}
if errors.is_empty() {
Ok(())
} else {
anyhow::bail!(
"Could not restore native GitHub stack membership after the push failed:\n{}",
errors.join("\n")
)
}
}
async fn github_review_bodies(
preferred_account: Option<&but_github::GithubAccountIdentifier>,
owner: &str,
repo: &str,
reviews: &[ForgeReviewUpdate],
storage: &but_forge_storage::Controller,
) -> Result<(Vec<Option<Option<String>>>, Vec<String>)> {
let mut bodies = Vec::with_capacity(reviews.len());
let mut errors = Vec::new();
for review in reviews {
if review.update_description {
bodies.push(Some(review.body.clone()));View on GitHub (pinned to 58e5313667)