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
- Read the embedded status and body for the exact GitLab error.
- If 404, re-fetch the MR by IID to confirm it still exists in the project.
- If 400/422, validate updated fields (e.g. target branch exists, state_event is 'close'/'reopen').
- If 401/403, refresh the token and confirm write (Developer+ / Maintainer) access.
- 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
- Fetch the MR first to confirm it exists and is open before updating.
- Validate any target branch change against the project's branch list.
- Refresh tokens proactively in long-running sessions.
- Check user role (Developer+/Maintainer) for MRs touching protected branches.
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
- Failed to create merge request
- Failed to get merge request
- Failed to get MR merge status
- Failed to merge merge request
- Anthropic API error ( )
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)