gitbutlerapp/gitbutler · error · anyhow::Error

Failed to list GitHub stacks: {}

Error message

Failed to list GitHub stacks: {}

What it means

GET /repos/{o}/{r}/stacks?pull_request=N returned a non-2xx status. A 404 is already translated internally to Ok(None) (stacks not present/unsupported), so this message means a genuine failure: authentication, permissions, rate limiting, or a server fault on the Stacks endpoint.

Source

Thrown at crates/but-github/src/stacks.rs:292

impl GitHubClient {
    /// `Ok(None)` means the repository does not expose the native stacks endpoint.
    async fn stacks_for_pull_request(
        &self,
        owner: &str,
        repo: &str,
        review_number: i64,
    ) -> Result<Option<Vec<Stack>>> {
        let response = self
            .client
            .get(format!("{}/repos/{owner}/{repo}/stacks", self.base_url))
            .query(&[("pull_request", review_number)])
            .send()
            .await?;
        if response.status() == reqwest::StatusCode::NOT_FOUND {
            return Ok(None);
        }
        if !response.status().is_success() {
            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!(

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Read the wrapped status and body - 401/403 means re-authenticate or fix permissions, 429 means back off
  2. Confirm the account can read the repository
  3. Retry once with backoff for transient failures
Defensive patterns

Strategy: try-catch

Try / catch

match client.list_stacks(owner, repo, pr_number).await {
    Ok(stacks) => stacks,
    Err(e) if e.to_string().starts_with("Failed to list GitHub stacks") => {
        log::warn!("stacks listing failed (possibly unsupported/rate-limited): {e}");
        None // degrade gracefully: stacks are optional metadata
    }
    other => other?,
}

Prevention

When it happens

Trigger: Token lacks read access to the repo; primary or secondary rate limits; GitHub Stacks feature-rollout gaps; GitHub Enterprise instances without the stacks endpoint answering 5xx.

Common situations: Beta API surface behind flags; heavy automation hitting rate limits; enterprise proxies in front of the API.

Related errors


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