gitbutlerapp/gitbutler · error
Failed to merge pull request
Error message
Failed to merge pull request: {status} - {error_text} What it means
Thrown by merge_pull_request when the HTTP POST that merges a Bitbucket pull request returns a non-success status. The message carries the HTTP status plus Bitbucket's response body, which typically explains why the merge was rejected (conflicts, unmet checks, insufficient merge strategies).
Solutions
- Read the error_text in the message — it names the failing merge check or conflict
- Re-run/repair CI checks on the PR's source commit before merging
- Pull/resolve merge conflicts on the source branch and push, then retry
- Ensure the token/account has merge permission on the repository
Example fix
// before
client.merge_pull_request(workspace, repo_slug, id, params).await?;
// after
match client.merge_pull_request(workspace, repo_slug, id, params).await {
Ok(()) => {},
Err(e) if e.to_string().contains("409") => anyhow::bail!("PR #{id} has conflicts; resolve and retry"),
Err(e) => return Err(e),
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check: required checks green and PR open
let pr_state = get_pr_state(ws, slug, id)?;
anyhow::ensure!(pr_state == "OPEN", "PR #{id} is not open for merge"); Try / catch
match client.merge_pull_request(ws, slug, id, params).await {
Err(e) if e.to_string().contains("conflict") || e.to_string().contains("400") => resolve_conflicts_then_retry()?,
other => other?,
} Prevention
- Verify CI checks pass before merging
- Refresh the source branch and resolve conflicts before merge attempts
- Ensure the account has merge permission
- Handle 'already merged' errors as idempotent success in automation
When it happens
Trigger: Merging a PR that is not open (404/400), unresolved merge conflicts (400), failing required build checks or merge checks, token without write/merge permission (403), or a merge strategy the repository disallows.
Common situations: Attempting to merge after the branch moved and conflicts appeared; required CI checks failing; user token lacking merge rights; PR already merged by someone else concurrently.
Related errors
- Failed to decline pull request
- Failed to update pull request
- Bitbucket request failed
- Bitbucket request failed
- Failed to create pull request
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/70cd431c938a7995.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-bitbucket/src/client.rs:461
Ok(())
}
pub async fn merge_pull_request(&self, params: &MergePullRequestParams<'_>) -> Result<()> {
let body = MergePullRequestBody {
merge_strategy: params.strategy.as_str(),
};
let url = format!(
"{}/repositories/{}/{}/pullrequests/{}/merge",
self.base_url,
urlencoding::encode(params.workspace),
urlencoding::encode(params.repo_slug),
params.id,
);
let response = self.client.post(&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 merge pull request: {status} - {error_text}");
}
Ok(())
}
/// Decline (close) a pull request.
pub async fn decline_pull_request(
&self,
workspace: &str,
repo_slug: &str,
id: i64,
) -> Result<()> {
let url = format!(
"{}/repositories/{}/{}/pullrequests/{}/decline",
self.base_url,
urlencoding::encode(workspace),
urlencoding::encode(repo_slug),
id,
);View on GitHub (pinned to 58e5313667)