Misleading "does not have valid YAML syntax" error when a nested include's include:rules filter out all of its includes
Summary
When an included file contains only include: entries that are all removed by their include:rules: (and no other keys), that file expands to an empty hash. The parent then reports a misleading error:
Included file `<parent>.yml` does not have valid YAML syntax!The YAML is perfectly valid — the real cause is that include:rules: filtered out every nested include, leaving the file empty.
Steps to reproduce
.gitlab-ci.yml:
include:
- local: nested.ymlnested.yml:
include:
- local: .child.yml
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"Run a push pipeline. The .child.yml include is filtered out (its rule only matches merge_request_event), so nested.yml expands to an empty hash.
Expected
Either a clear message indicating the include resolved to nothing because of include:rules: filtering, or the empty nested include treated as an empty (no-op) inclusion — not a "valid YAML syntax" error.
Actual
Included file `.gitlab-ci.yml` does not have valid YAML syntax!The pipeline is persisted as a failed config_error.
Root cause
In Gitlab::Ci::Config::External::Processor#perform (lib/gitlab/ci/config/external/processor.rb), when all includes of a file are filtered out, @external_files is empty and the method early-returns @values with the include: keyword still present:
def perform
return @values if @external_files.empty?
# ... merge, append inline, remove_include_keyword!, validate
endDownstream, File::Base#validate_hash! sees to_hash as blank and raises the "does not have valid YAML syntax" error (lib/gitlab/ci/config/external/file/base.rb).
Notes
- This is pre-existing behavior on
master, independent of !246515 (merged) (which handles the top-level "no visible jobs" case). Confirmed by reproducing against a cleanmasterlib. - Related: #591780 and !246515 (merged).