Repository navigation
[CHORE] Catch duplicate YAML keys in pre-commit - #2340
Open
vishnuszipstack wants to merge 1 commit into
Open
vishnuszipstack wants to merge 1 commit into
vishnuszipstack wants to merge 1 commit into
Conversation
`check-yaml` cannot catch a duplicate mapping key. It runs with `--unsafe`,
which parses for syntax without constructing the document, and even without
that flag it loads via `yaml.safe_load`, which resolves a duplicate to the
last occurrence silently. Docker Compose's loader rejects them outright, so
the two disagree -- and the strict one is the one in CI.
That gap shipped a `tests/compose/docker-compose.test.yaml` carrying a
second `backend:` key alongside the one at line 5. pre-commit passed it;
the e2e tier then died at `compose up` in 0.4s, before a container started:
line 93: mapping key "backend" already defined at line 5
Adds yamllint pinned at v1.38.0 with `key-duplicates` and nothing else.
Verified, rather than assumed:
- Reintroduced the exact incident shape; the hook FAILS naming the file,
line and key, while `check-yaml` PASSES on that same file. A guard that
does not fail on the bug it targets is worthless, so this is the test
that mattered.
- Covers `.yml` as well as `.yaml` -- confirmed by planting a duplicate in
`.github/ISSUE_TEMPLATE/config.yml`, since a hook matching no files also
reports "Passed".
- Clean on the current tree: all 22 tracked YAML files, zero findings, so
no exclusions and no per-file waivers.
Every other yamllint rule is off deliberately. `extends: default` reports
333 findings across those same files (270 of them line-length), which would
get the hook disabled rather than the files fixed. Listing the one rule
explicitly also means a future version bump cannot widen its scope.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Contributor
|
Contributor
Unstract test resultsPer-group results
Critical paths
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



What
yamllint(pinnedv1.38.0) to.pre-commit-config.yamlwith thekey-duplicatesrule and nothing else.check yaml for duplicate keys, so a failure says what it is.Why
check-yamlcannot catch a duplicate mapping key:args: [--unsafe], which parses for syntax without constructing the document;yaml.safe_load, which resolves a duplicate to the last occurrence silently.Docker Compose's loader rejects duplicates outright. So the two loaders disagree, and the strict one is the one that runs in CI.
That gap shipped a
tests/compose/docker-compose.test.yamlcarrying a secondbackend:key alongside the one at line 5. pre-commit passed it; the e2e tier then died atcompose upin 0.4s, before a single container started:The failure mode is nasty because the local signal is green and the file looks fine — the second key simply replaces the first, taking the service's
image:pin and every other env var with it.How
The rule is named inline rather than in a
.yamllint.yaml, so the one rule in force is visible at the point of use and a futurerevbump cannot widen the scope.Every other yamllint rule is off, deliberately. The repo has no yamllint baseline and this hook is not an invitation to adopt one:
extends: defaultreports 333 findings across the same files (270 of themline-length), which would get the hook disabled rather than the files fixed.Can this PR break any existing features. If yes, please list possible items. If no, please explain why.
.pre-commit-config.yaml.types: [file, yaml]is upstream's own selector; no customfiles:pattern to drift.Database Migrations
Env Config
Relevant Docs
key-duplicatescheck-yaml--unsafeRelated Issues or PRs
Dependencies Versions
yamllintv1.38.0(released 2026-01-13), new pre-commit hook repo. No application dependency is added — pre-commit builds it in its own isolated env.Notes on Testing
check-yamlpasses on that same file. A guard that does not fail on the bug it targets is worthless..ymlis covered as well as.yaml, by planting a duplicate in.github/ISSUE_TEMPLATE/config.yml. A hook that matches no files also reports "Passed", so this needed checking separately.pre-commit run yamllint --all-filespasses on the current tree (22 files, 0 findings).pre-commit validate-configpasses.check yaml.To reproduce the catch yourself:
Screenshots
N/A
Checklist
I have read and understood the Contribution Guidelines.
🤖 Generated with Claude Code