GitLab CI/CD Associate study materials
GitLab CI/CD Associate study resources

GitLab CI/CD Associate: Troubleshooting Pipelines and Merge Request Pipelines

GitLab CI/CD Associate · Work through your exam, one topic at a time.

All guide sections

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/extends merging 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 pending with "no matching runner" is a tag or runner-scope problem, not a script problem.
  • rules:changes compares against the target branch in MR pipelines; set compare_to when the comparison ref must be explicit.

Traps

  • Mixing only/except with rules.
  • Writing if: $CI_MERGE_REQUEST_IID in a job that also runs on push - the condition is false, the job vanishes, and the pipeline looks incomplete.
  • Assuming changes behaves identically on new branches, MR pipelines, and schedules.
  • Leaving CI_DEBUG_TRACE enabled in a shared project.