{"record":{"id":"0258bf598ea61551","repo":"gitbutlerapp/gitbutler","slug":"failed-to-add-to-github-stack","errorCode":null,"errorMessage":"Failed to add to GitHub stack: {}","messagePattern":"Failed to add to GitHub stack: (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-github/src/stacks.rs","lineNumber":335,"sourceCode":"\n    async fn add_to_stack(\n        &self,\n        owner: &str,\n        repo: &str,\n        stack_number: i64,\n        pull_requests: &[i64],\n    ) -> Result<()> {\n        let response = self\n            .client\n            .post(format!(\n                \"{}/repos/{owner}/{repo}/stacks/{stack_number}/add\",\n                self.base_url\n            ))\n            .json(&StackMembersBody { pull_requests })\n            .send()\n            .await?;\n        if !response.status().is_success() {\n            bail!(\n                \"Failed to add to GitHub stack: {}\",\n                response_error(response).await\n            );\n        }\n        Ok(())\n    }\n\n    async fn unstack(&self, owner: &str, repo: &str, stack_number: i64) -> Result<()> {\n        let response = self\n            .client\n            .post(format!(\n                \"{}/repos/{owner}/{repo}/stacks/{stack_number}/unstack\",\n                self.base_url\n            ))\n            .send()\n            .await?;\n        if !response.status().is_success() {\n            bail!(","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-github/src/stacks.rs#L317-L353","documentation":"POST /repos/{o}/{r}/stacks/{stack_number}/add returned a non-2xx status; the wrapped response explains why the given pull request(s) could not join the stack.","triggerScenarios":"The stack number no longer exists; a PR is already a member of a stack; the PR is closed; missing permissions; rate limiting.","commonSituations":"Stale stack numbers after an unstack or reorganization; concurrent modifications by other clients.","solutions":["Re-list stacks to refresh stack numbers before adding","Remove the PR from its current stack before adding it to another","Address auth or rate-limit causes indicated by the wrapped error"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"let stacks = client.list_stacks(owner, repo, pr_number).await?.unwrap_or_default();\nif !stacks.iter().any(|s| s.number == stack_number) {\n    anyhow::bail!(\"stack #{stack_number} no longer exists - re-list stacks\");\n}","typeGuard":null,"tryCatchPattern":"match client.add_to_stack(owner, repo, stack_number, &pr_ids).await {\n    Err(e) if e.to_string().starts_with(\"Failed to add to GitHub stack\") => {\n        let stacks = client.list_stacks(owner, repo, pr_number).await?;\n        reconcile_membership(&stacks, &pr_ids)?; // repair then retry once\n        client.add_to_stack(owner, repo, stack_number, &pr_ids).await\n    }\n    other => other,\n}","preventionTips":["Re-list stacks immediately before mutating them","Remove a PR from its current stack before adding it elsewhere","Serialize stack mutations to avoid concurrent clients"],"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"}