{"record":{"id":"67654c97375efb07","repo":"gitbutlerapp/gitbutler","slug":"failed-to-enable-merge-request-auto-merge-status","errorCode":null,"errorMessage":"Failed to enable merge request auto-merge: {status} - {error_text}","messagePattern":"Failed to enable merge request auto-merge: (.+?) - (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/but-gitlab/src/client.rs","lineNumber":500,"sourceCode":"                auto_merge: bool,\n            }\n\n            let url = format!(\n                \"{}/projects/{}/merge_requests/{}/merge\",\n                self.base_url, project_id, params.mr_iid\n            );\n\n            let response = self\n                .client\n                .put(&url)\n                .json(&EnableAutoMergeBody { auto_merge: true })\n                .send()\n                .await?;\n\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 enable merge request auto-merge: {status} - {error_text}\");\n            }\n\n            return Ok(());\n        }\n\n        let url = format!(\n            \"{}/projects/{}/merge_requests/{}/cancel_merge_when_pipeline_succeeds\",\n            self.base_url, project_id, params.mr_iid\n        );\n\n        let response = self.client.post(&url).send().await?;\n\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 disable merge request auto-merge: {status} - {error_text}\");\n        }\n","sourceCodeStart":482,"sourceCodeEnd":518,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but-gitlab/src/client.rs#L482-L518","documentation":"Thrown by GitLabClient::set_merge_request_auto_merge when params.enabled == true and GitLab rejects PUT /projects/:id/merge_requests/:iid/merge_when_pipeline_succeeds (body {auto_merge:true}). This endpoint is GitLab's 'Merge when pipeline succeeds' and it is picky: the classic failure is 406 Not Acceptable, returned when there is no pipeline running for the MR's HEAD, the MR is not mergeable, or merge is blocked by project settings. Status and response body are both included in the message.","triggerScenarios":"Enabling auto-merge when no pipeline is currently running for the MR head SHA (406); MR has conflicts so it is not mergeable (406); 'Pipelines must succeed' or 'merge checks' settings reject it (406); MR is a draft or already merged (405/406); auto-merge already enabled (406); account lacks Developer rights (403).","commonSituations":"User clicks 'merge when pipeline succeeds' before CI has registered/started a pipeline for the latest push; enabling auto-merge on a draft; retrying after the pipeline already finished (should plain-merge instead).","solutions":["Only offer auto-merge when a pipeline for the MR's HEAD is actually running — check via list_pipeline_jobs_for_ref","Verify is_mergeable via get_mr_merge_status first; resolve conflicts otherwise","If the pipeline already succeeded, call merge_merge_request directly instead of enabling auto-merge","For 403, confirm the account can merge into the target branch","Treat 'already enabled' (406 with that message) as success rather than an error"],"exampleFix":"// before\nclient.set_merge_request_auto_merge(&params).await?;\n\n// after: pre-check pipeline presence and mergeability\nlet jobs = client.list_pipeline_jobs_for_ref(params.project_id.clone(), &mr_source_branch).await?;\nensure!(!jobs.is_empty(), \"no pipeline running for this MR — cannot auto-merge\");\nlet st = client.get_mr_merge_status(params.project_id.clone(), params.mr_iid).await?;\nensure!(st.is_mergeable, \"MR has conflicts — cannot enable auto-merge\");\nclient.set_merge_request_auto_merge(&params).await?;","handlingStrategy":"validation","validationCode":"// Auto-merge needs a running pipeline and a mergeable MR\nlet st = client.get_mr_merge_status(params.project_id.clone(), params.mr_iid).await?;\nensure!(st.is_mergeable, \"MR is not mergeable\");\nlet jobs = client.list_pipeline_jobs_for_ref(params.project_id.clone(), &source_branch).await?;\nensure!(!jobs.is_empty(), \"no pipeline running for MR head\");\nclient.set_merge_request_auto_merge(&params).await?;","typeGuard":null,"tryCatchPattern":"if let Err(err) = client.set_merge_request_auto_merge(&params).await {\n    if err.to_string().contains(\"406\") { /* explain: no pipeline / checks not satisfied / already enabled */ }\n    else { return Err(err); }\n}","preventionTips":["Only show 'merge when pipeline succeeds' when a pipeline is actually running for the HEAD sha","Treat an already-enabled 406 as success to keep flows idempotent"],"tags":["gitlab","http","auto-merge","pipeline","merge-request","rust"],"backgroundTag":"gitlab-auto-merge-error","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}