{"record":{"id":"0594efebdd3d48d3","repo":"gitbutlerapp/gitbutler","slug":"failed-to-list-github-stacks","errorCode":null,"errorMessage":"Failed to list GitHub stacks: {}","messagePattern":"Failed to list GitHub stacks: (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-github/src/stacks.rs","lineNumber":292,"sourceCode":"impl GitHubClient {\n    /// `Ok(None)` means the repository does not expose the native stacks endpoint.\n    async fn stacks_for_pull_request(\n        &self,\n        owner: &str,\n        repo: &str,\n        review_number: i64,\n    ) -> Result<Option<Vec<Stack>>> {\n        let response = self\n            .client\n            .get(format!(\"{}/repos/{owner}/{repo}/stacks\", self.base_url))\n            .query(&[(\"pull_request\", review_number)])\n            .send()\n            .await?;\n        if response.status() == reqwest::StatusCode::NOT_FOUND {\n            return Ok(None);\n        }\n        if !response.status().is_success() {\n            bail!(\n                \"Failed to list GitHub stacks: {}\",\n                response_error(response).await\n            );\n        }\n        Ok(Some(response.json().await?))\n    }\n\n    async fn create_stack(&self, owner: &str, repo: &str, desired: &[i64]) -> Result<()> {\n        let response = self\n            .client\n            .post(format!(\"{}/repos/{owner}/{repo}/stacks\", self.base_url))\n            .json(&StackMembersBody {\n                pull_requests: desired,\n            })\n            .send()\n            .await?;\n        if !response.status().is_success() {\n            bail!(","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-github/src/stacks.rs#L274-L310","documentation":"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.","triggerScenarios":"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.","commonSituations":"Beta API surface behind flags; heavy automation hitting rate limits; enterprise proxies in front of the API.","solutions":["Read the wrapped status and body - 401/403 means re-authenticate or fix permissions, 429 means back off","Confirm the account can read the repository","Retry once with backoff for transient failures"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match client.list_stacks(owner, repo, pr_number).await {\n    Ok(stacks) => stacks,\n    Err(e) if e.to_string().starts_with(\"Failed to list GitHub stacks\") => {\n        log::warn!(\"stacks listing failed (possibly unsupported/rate-limited): {e}\");\n        None // degrade gracefully: stacks are optional metadata\n    }\n    other => other?,\n}","preventionTips":["Treat 404 as 'no stacks' (the client already does) and other failures as transient first","Rate-limit stack queries in polling loops","Verify the account can read the repo before stack operations"],"tags":["github","stacks","rest-api","pull-request"],"backgroundTag":"github-api-request-failed","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}