Skip to content

fix: accept null merged_yaml/includes in CI lint result - #639

Open
nkz-soft wants to merge 1 commit into
zereight:mainfrom
nkz-soft:fix/ci-lint-null-merged-yaml
Open

fix: accept null merged_yaml/includes in CI lint result#639
nkz-soft wants to merge 1 commit into
zereight:mainfrom
nkz-soft:fix/ci-lint-null-merged-yaml

Conversation

@nkz-soft

@nkz-soft nkz-soft commented Aug 5, 2026

Copy link
Copy Markdown

Fixes #638.

Problem

validate_ci_lint (and validate_project_ci_lint) throw instead of returning a result whenever the CI config is invalid — exactly the case the tool is called for. On a valid config they work, which is why the bug stays invisible until a user actually has a broken .gitlab-ci.yml.

GitLab returns merged_yaml: null and includes: null for an invalid config. GitLabCiLintResultSchema declared both as .optional(), which in Zod accepts undefined but rejects null, so .parse() threw and the caller got a schema error instead of the lint result:

-32603  Invalid arguments: merged_yaml: Expected string, received null, includes: Expected array, received null

The actual explanation from GitLab — e.g. image is defined in top-level and `default:` entry — never reached the caller.

Change

.optional().nullish() on the two fields GitLab actually nulls. Same class as #575, so the regression test goes next to those cases in test/nullable-gitlab-response-fields.test.ts.

Scope is deliberately minimal: warnings and jobs come back as arrays in every response I observed, so I left them alone rather than widening the schema speculatively.

Verification

The new test reproduces the reported failure before the schema change:

not ok 3 - ci lint result accepts null merged_yaml/includes on an invalid config
        "message": "Expected string, received null"
# pass 2
# fail 1

and passes after it. All three CI gates pass locally:

Gate Result
npm run test:mock exit 0, 66 suites, 0 failures
npm run test:consumer-smoke Consumer install smoke passed.
npx tsc --noEmit clean

Reproduced against a self-hosted GitLab 19.2.0-ee on 2.1.42 and 2.1.46, stdio transport with PAT auth, using this config:

default:
  image: alpine:3.20

stages:
  - build

image:
  stage: build
  script:
    - echo build

Direct API response for it:

{"valid":false,"errors":["image is defined in top-level and `default:` entry"],"warnings":[],"merged_yaml":null,"includes":null}

Why it matters

An agent using this tool to validate CI changes cannot distinguish "the config is invalid" from "the tool is broken". In our case the agent concluded the latter, fell back to prettier --check — which checks YAML formatting, not GitLab CI semantics — and reported success on a config that was invalid. The two errors it needed to catch (a job named image, and needs referencing a nonexistent job) are both caught by the lint endpoint in under a second and are both invisible to a formatter.

GitLab returns null (not an omitted field) for merged_yaml and includes
whenever the CI config is invalid. Zod's .optional() accepts undefined but
rejects null, so GitLabCiLintResultSchema.parse() threw and validate_ci_lint
surfaced a schema error instead of the lint result — failing in exactly the
case the tool is called for. On a valid config it worked, which kept the bug
invisible.

Same class as zereight#575; regression test added alongside those cases.

Fixes zereight#638
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d3c3940f-33b1-42a7-8c73-0b4a8a5863c8

📥 Commits

Reviewing files that changed from the base of the PR and between 926d42c and 90eaf59.

📒 Files selected for processing (2)
  • schemas.ts
  • test/nullable-gitlab-response-fields.test.ts
📜 Recent review details
🔇 Additional comments (2)
schemas.ts (1)

321-324: LGTM!

test/nullable-gitlab-response-fields.test.ts (1)

4-4: LGTM!

Also applies to: 29-44


📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of invalid GitLab CI configurations by accepting responses where merged YAML and included configuration data are returned as null.
    • Preserved validation errors for other malformed response fields.
  • Tests

    • Added coverage for nullable CI lint response fields.

Walkthrough

GitLabCiLintResultSchema now accepts null for merged_yaml and includes. A regression test verifies that invalid GitLab CI lint responses preserve their status and errors.

Changes

CI lint response validation

Layer / File(s) Summary
Nullable CI lint response schema
schemas.ts, test/nullable-gitlab-response-fields.test.ts
The schema accepts null or omitted values for merged_yaml and includes. Tests validate invalid responses with both fields set to null.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: zereight, vrajpal-jhala, wujidadi

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the primary schema change: accepting null merged_yaml and includes values in CI lint results.
Description check ✅ Passed The description explains the invalid CI configuration failure, the nullability fix, regression coverage, and verification results.
Linked Issues check ✅ Passed The schema changes and regression test satisfy issue #638 by allowing invalid CI lint results with null merged_yaml and includes values.
Out of Scope Changes check ✅ Passed The changes are limited to the required schema updates and focused regression test, with no unrelated code changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

validate_ci_lint throws on every invalid config: merged_yaml/includes are null, schema uses .optional()

1 participant