Troubleshooting Pipelines and Merge Request Pipelines
This domain tests diagnosis: reading pipeline sources, building correct merge request pipelines without duplicates, and interpreting the failure messages GitLab actually produces.
Pipeline sources and MR pipelines
CI_PIPELINE_SOURCE explains why a pipeline exists: push, merge_request_event, schedule, web, api, trigger, parent_pipeline, pipeline, ondemand_dast_scan. The CI_MERGE_REQUEST_* variables (CI_MERGE_REQUEST_IID, CI_MERGE_REQUEST_TARGET_BRANCH_NAME, CI_MERGE_REQUEST_EVENT_TYPE) exist only in merge_request_event pipelines - a job that reads them in a branch pipeline gets empty values, which is often the real bug behind "the MR job did nothing".
Merged-results and merge-train pipelines are still merge_request_event; CI_MERGE_REQUEST_EVENT_TYPE distinguishes detached, merged_result, and merge_train.
Avoiding duplicate pipelines
Pushing to a branch with an open MR can create both a branch pipeline and an MR pipeline. Fix it at the top of the file:
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
Reasoning: MR pipelines are always allowed; a branch pipeline is suppressed when an MR is already open; otherwise branch pipelines run, which also covers the default branch because CI_OPEN_MERGE_REQUESTS is empty there. Order matters - the first match wins, so the never rule must precede the general branch rule.
Diagnosis tools
- CI Lint validates syntax and simulates
include/extendsmerging before you push. CI_DEBUG_TRACE: "true"produces verbose shell tracing; it can print secrets, so use it on a throwaway branch and disable it afterwards.- Exit code 137 means SIGKILL - almost always the job timeout or a runner out of memory; exit code 1 is your own script failing.
- A job stuck in
pendingwith "no matching runner" is a tag or runner-scope problem, not a script problem. rules:changescompares against the target branch in MR pipelines; setcompare_towhen the comparison ref must be explicit.
Traps
- Mixing
only/exceptwithrules. - Writing
if: $CI_MERGE_REQUEST_IIDin a job that also runs on push - the condition is false, the job vanishes, and the pipeline looks incomplete. - Assuming
changesbehaves identically on new branches, MR pipelines, and schedules. - Leaving
CI_DEBUG_TRACEenabled in a shared project.