exists keyword does not resolve correctly when used inside rules with nested !reference

Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.

  • Close this issue

Summary

Using exists keyword inside rules section with nested !reference produces error: This GitLab CI configuration is invalid: jobs:<job_name>:rules:rule exists should be an array of strings.

Steps to reproduce

The following .gitlab-ci.yml produces the error:

.global_exists:
  exists: 
  - 'hello/world'

.global_rules:
  rules: 
  - if: $CI_COMMIT_BRANCH
    exists: !reference [.global_exists, exists]

test:
    stage: test
    script:
        - echo "Hello World"
    rules:
      !reference [.global_rules, rules]

The merged/full YAML it produces is:

---
".global_exists":
  exists:
  - hello/world
".global_rules":
  rules:
  - if: "$CI_COMMIT_BRANCH"
    exists:
    - hello/world
test:
  stage: test
  script:
  - echo "Hello World"
  rules:
  - if: "$CI_COMMIT_BRANCH"
    exists: !reference
      data:
        :tag: "!reference"
        :style: 1
        :seq:
        - ".global_exists"
        - exists
        :scalar:
        :map: {}
      resolved_status: :done
      resolved_value:
      - hello/world

As the faulty resolution disturbs the array structure, it results in the above error. The actual merged output should only have resolved_value value for exists I believe.

What is the current bug behavior?

exists keyword does not resolve correctly when used inside rules with nested !reference.

What is the expected correct behavior?

exists keyword should resolve correctly when used inside rules with nested !reference.

Relevant logs and/or screenshots

This GitLab CI configuration is invalid: jobs:<job_name>:rules:rule exists should be an array of strings.

Results of GitLab environment info

Expand for output related to GitLab environment info

(For installations with omnibus-gitlab package run and paste the output of:
`sudo gitlab-rake gitlab:env:info`)

(For installations from source run and paste the output of:
`sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`)

Results of GitLab application Check

Happens at GitLab.com and Self-managed.

Workarounds

Cut one level of nesting, either at rules or at exists sections in the above YAML.

Example:

.global_exists:
  exists: 
  - 'hello/world'

.global_rules:
  rules: 
   - if: $CI_COMMIT_BRANCH
     exists:
        - 'hello/world'

test:
    stage: test
    script:
        - echo "Hello World"
    rules:
      !reference [.global_rules, rules]

Merged/full YAML for the above example:

---
".global_exists":
  exists:
  - hello/world
".global_rules":
  rules:
  - if: "$CI_COMMIT_BRANCH"
    exists:
    - hello/world
test:
  stage: test
  script:
  - echo "Hello World"
  rules:
  - if: "$CI_COMMIT_BRANCH"
    exists:
    - hello/world
Edited Aug 26, 2025 by 🤖 GitLab Bot 🤖
Assignee Loading
Time tracking Loading