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

  1. Read the wrapped body - it names the invalid PR or the violated constraint
  2. Ensure all PRs are open in the same repo and form a parent/child branch chain
  3. Remove conflicting stack membership before creating
  4. 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

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


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/2af6ec6417a7916d. Report an issue: GitHub.