gitbutlerapp/gitbutler · error

Failed to update pull request

Error message

Failed to update pull request: {status} - {error_text}

What it means

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.

Solutions

  1. Check the error_text in the message for Bitbucket's specific reason (e.g. 'not found', 'forbidden', validation message)
  2. Verify the token has repository write permission for PR updates
  3. Confirm the PR id exists and the PR is still open (not merged/declined)
  4. Validate the update body (destination branch name, draft flag) before calling

Example fix

// before
client.set_pull_request_draft_state(workspace, repo_slug, id, true).await?;
// after
let pr = client.fetch_repo(workspace, repo_slug).await.ok(); // confirm access first
client.set_pull_request_draft_state(workspace, repo_slug, id, true).await
    .map_err(|e| anyhow::anyhow!("marking PR #{id} draft: {e:#}"))?;
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure PR is open and token has write scope before updating
let can_write = check_repo_write_scope(token)?;
anyhow::ensure!(can_write, "token lacks write access for PR update");

Try / catch

match client.update_pull_request(ws, slug, id, body).await {
    Err(e) if e.to_string().contains("404") => anyhow::bail!("PR #{id} no longer exists"),
    Err(e) if e.to_string().contains("40") => anyhow::bail!("permission/auth problem: {e}"),
    other => other?,
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/06a536185c37bb4e. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-bitbucket/src/client.rs:406

    async fn send_pr_update(
        &self,
        workspace: &str,
        repo_slug: &str,
        id: i64,
        body: &UpdatePullRequestBody<'_>,
    ) -> Result<BitbucketPullRequest> {
        let url = format!(
            "{}/repositories/{}/{}/pullrequests/{}",
            self.base_url,
            urlencoding::encode(workspace),
            urlencoding::encode(repo_slug),
            id,
        );
        let response = self.client.put(&url).json(body).send().await?;
        if !response.status().is_success() {
            let status = response.status();
            let error_text = response.text().await.unwrap_or_default();
            bail!("Failed to update pull request: {status} - {error_text}");
        }
        let pr: BitbucketApiPullRequest = response.json().await?;
        Ok(pr.into())
    }

    pub async fn update_pull_request(
        &self,
        params: &UpdatePullRequestParams<'_>,
    ) -> Result<BitbucketPullRequest> {
        let ctx = self
            .fetch_pr_edit_context(params.workspace, params.repo_slug, params.id)
            .await?;
        let body = build_update_body(
            &ctx,
            params.title,
            params.description,
            params.target_branch,
            None,

View on GitHub (pinned to 58e5313667)