{"record":{"id":"06a536185c37bb4e","repo":"gitbutlerapp/gitbutler","slug":"failed-to-update-pull-request-status-error-t","errorCode":null,"errorMessage":"Failed to update pull request: {status} - {error_text}","messagePattern":"Failed to update pull request: (.+?) - (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-bitbucket/src/client.rs","lineNumber":406,"sourceCode":"    async fn send_pr_update(\n        &self,\n        workspace: &str,\n        repo_slug: &str,\n        id: i64,\n        body: &UpdatePullRequestBody<'_>,\n    ) -> Result<BitbucketPullRequest> {\n        let url = format!(\n            \"{}/repositories/{}/{}/pullrequests/{}\",\n            self.base_url,\n            urlencoding::encode(workspace),\n            urlencoding::encode(repo_slug),\n            id,\n        );\n        let response = self.client.put(&url).json(body).send().await?;\n        if !response.status().is_success() {\n            let status = response.status();\n            let error_text = response.text().await.unwrap_or_default();\n            bail!(\"Failed to update pull request: {status} - {error_text}\");\n        }\n        let pr: BitbucketApiPullRequest = response.json().await?;\n        Ok(pr.into())\n    }\n\n    pub async fn update_pull_request(\n        &self,\n        params: &UpdatePullRequestParams<'_>,\n    ) -> Result<BitbucketPullRequest> {\n        let ctx = self\n            .fetch_pr_edit_context(params.workspace, params.repo_slug, params.id)\n            .await?;\n        let body = build_update_body(\n            &ctx,\n            params.title,\n            params.description,\n            params.target_branch,\n            None,","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-bitbucket/src/client.rs#L388-L424","documentation":"Thrown by send_pr_update when the HTTP PUT used to update a Bitbucket pull request (title, description, draft state, destination) returns a non-success status. The error includes both the HTTP status and the response body text, which usually contains Bitbucket's structured error explanation.","triggerScenarios":"update_pull_request or set_pull_request_draft_state targets a PR id that doesn't exist (404), the token lacks write access (403/401), the payload is rejected (400 — e.g. invalid destination branch or draft state value), or the PR is in a state that can't be edited (409/500).","commonSituations":"Merged or declined PR being updated; bot token with read-only scope; wrong PR id after the PR was deleted; invalid reviewer/destination values in the update body.","solutions":["Check the error_text in the message for Bitbucket's specific reason (e.g. 'not found', 'forbidden', validation message)","Verify the token has repository write permission for PR updates","Confirm the PR id exists and the PR is still open (not merged/declined)","Validate the update body (destination branch name, draft flag) before calling"],"exampleFix":"// before\nclient.set_pull_request_draft_state(workspace, repo_slug, id, true).await?;\n// after\nlet pr = client.fetch_repo(workspace, repo_slug).await.ok(); // confirm access first\nclient.set_pull_request_draft_state(workspace, repo_slug, id, true).await\n    .map_err(|e| anyhow::anyhow!(\"marking PR #{id} draft: {e:#}\"))?;","handlingStrategy":"try-catch","validationCode":"// ensure PR is open and token has write scope before updating\nlet can_write = check_repo_write_scope(token)?;\nanyhow::ensure!(can_write, \"token lacks write access for PR update\");","typeGuard":null,"tryCatchPattern":"match client.update_pull_request(ws, slug, id, body).await {\n    Err(e) if e.to_string().contains(\"404\") => anyhow::bail!(\"PR #{id} no longer exists\"),\n    Err(e) if e.to_string().contains(\"40\") => anyhow::bail!(\"permission/auth problem: {e}\"),\n    other => other?,\n}","preventionTips":["Check PR state (open) before mutating it","Use tokens with repository write scope","Validate destination/draft fields before sending","Surface error_text from the message to users — it names the exact API rejection"],"tags":["network","http","bitbucket","pull-request","api-error"],"backgroundTag":"upstream-api-error","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}