gitbutlerapp/gitbutler · error

Failed to update merge request

Error message

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

What it means

GitLab rejected the merge-request update PUT with a non-success HTTP status. The error message carries the status code and raw response body so the caller can identify whether it was authorization, validation, or a missing resource.

Solutions

  1. Read the embedded status and body for the exact GitLab error.
  2. If 404, re-fetch the MR by IID to confirm it still exists in the project.
  3. If 400/422, validate updated fields (e.g. target branch exists, state_event is 'close'/'reopen').
  4. If 401/403, refresh the token and confirm write (Developer+ / Maintainer) access.
  5. Retry with backoff on 5xx.
Defensive patterns

Strategy: try-catch

Validate before calling

// validate the MR exists and fields are updatable before the PUT
let mr = gitlab.get_merge_request(project_id, mr_iid).await?; // 404 surfaces early
anyhow::ensure!(mr.state == "opened", "cannot update MR in state '{}'", mr.state);
if let Some(tb) = &new_target_branch {
    anyhow::ensure!(branch_exists(project_id, tb).await?, "target branch '{tb}' does not exist");
}

Try / catch

match gitlab.update_merge_request(project_id, mr_iid, &body).await {
    Ok(mr) => mr,
    Err(e) if e.to_string().contains("404") => refetch_mr_or_skip(),
    Err(e) if e.to_string().contains("403") => refresh_credentials(),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling update_merge_request when PUT /projects/{id}/merge_requests/{mr_iid} returns 4xx/5xx — 404 for a wrong mr_iid or project, 400/422 for invalid field updates (bad target_branch, invalid state_event), 401/403 for token/permission problems.

Common situations: Updating an MR that was closed/deleted or whose IID changed after a project transfer; attempting to retarget to a nonexistent branch; token expired mid-session; trying to update MRs on protected branches without sufficient role.

Related errors


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

Appendix: source

Thrown at crates/but-gitlab/src/client.rs:468

                .await?;
            Some(update_draft_state_in_title(title, mr.draft))
        } else {
            None
        };

        let body = UpdateMergeRequestBody {
            title: title.as_deref(),
            description: params.description,
            target_branch: params.target_branch,
            state_event: params.state_event,
        };

        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 merge request: {status} - {error_text}");
        }

        let mr: GitLabMergeRequest = response.json().await?;
        Ok(mr.into())
    }

    pub async fn merge_merge_request(&self, params: &MergeMergeRequestParams) -> Result<()> {
        #[derive(Serialize)]
        struct MergeMergeRequestBody {
            #[serde(skip_serializing_if = "Option::is_none")]
            squash: Option<bool>,
        }

        let url = format!(
            "{}/projects/{}/merge_requests/{}/merge",
            self.base_url, params.project_id, params.mr_iid
        );

View on GitHub (pinned to 58e5313667)