gitbutlerapp/gitbutler · error · anyhow::Error
Failed to create GitHub stack: {}
Error message
Failed to create GitHub stack: {} What it means
POST /repos/{o}/{r}/stacks with the desired pull-request list returned a non-2xx status; the wrapped response body carries GitHub's reason for refusing to create the stack.
Source
Thrown at crates/but-github/src/stacks.rs:310
bail!(
"Failed to list GitHub stacks: {}",
response_error(response).await
);
}
Ok(Some(response.json().await?))
}
async fn create_stack(&self, owner: &str, repo: &str, desired: &[i64]) -> Result<()> {
let response = self
.client
.post(format!("{}/repos/{owner}/{repo}/stacks", self.base_url))
.json(&StackMembersBody {
pull_requests: desired,
})
.send()
.await?;
if !response.status().is_success() {
bail!(
"Failed to create GitHub stack: {}",
response_error(response).await
);
}
Ok(())
}
async fn add_to_stack(
&self,
owner: &str,
repo: &str,
stack_number: i64,
pull_requests: &[i64],
) -> Result<()> {
let response = self
.client
.post(format!(
"{}/repos/{owner}/{repo}/stacks/{stack_number}/add",View on GitHub (pinned to caf1f223d3)
Solutions
- Read the wrapped body - it names the invalid PR or the violated constraint
- Ensure all PRs are open in the same repo and form a parent/child branch chain
- Remove conflicting stack membership before creating
- Back off on 429/5xx and retry
Defensive patterns
Strategy: try-catch
Validate before calling
let prs = client.list_pull_requests(owner, repo, &Default::default()).await?;
let all_open = desired.iter().all(|n| prs.iter().any(|pr| &pr.number == n && pr.state == PrState::Open));
if !all_open { anyhow::bail!("stack creation requires all PRs to be open in {owner}/{repo}"); } Try / catch
if let Err(e) = client.create_stack(owner, repo, &desired).await {
if e.to_string().starts_with("Failed to create GitHub stack") {
// body text names the offending PR: surface it verbatim
return Err(e.context(format!("creating stack for PRs {desired:?}")));
}
return Err(e);
} Prevention
- Verify every PR number is open and in the same repo before stacking
- Build stacks from chained branches only
- Resolve conflicting stack membership before creating a new stack
When it happens
Trigger: A listed PR is closed, invalid, or from another repo; the PRs cannot form a stack (branches not chained); the acting user lacks permission to manage stacks; a PR is already in a different stack; rate limits.
Common situations: Trying to stack unrelated PRs; stale PR numbers; concurrent stack edits from other clients.
Related errors
- Failed to list GitHub stacks: {}
- Failed to add to GitHub stack: {}
- Failed to unstack GitHub stack: {}
- Could not restore all review targets after the push failed:
- GitHub GraphQL enablePullRequestAutoMerge returned an empty
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/2af6ec6417a7916d.
Report an issue: GitHub.