A CI config failed with a parser error that pointed at a line I had not edited. The actual cause was a tab character in the indentation four lines earlier, inserted by an editor I did not realize had different whitespace settings. YAML forbids tabs for indentation, the parser complained late, and I lost an afternoon to a character I could not see.
That was the day I stopped treating config as text I can eyeball. The failure was not exotic; it was one of a small family of structural mistakes that a machine can find instantly and a human reliably misses. Tabs, inconsistent indentation, duplicate keys, anchors that point at a name someone renamed. None of them require judgement to detect. They require a ruleset and an exact line number.
Why this is a ruleset and not a guess
YAML is a defined format with defined rules. Whether indentation uses spaces, whether a key appears twice in the same mapping, whether an alias resolves to an anchor that exists: these are decidable questions. There is no ambiguity for a model to reason about, and I did not want one in this loop. A probabilistic answer to "is there a duplicate key here" is worse than no answer, because I would still have to check it.
YAMLValidator runs a deterministic lint ruleset against the config you paste. It covers tabs, indentation, duplicate keys, anchors and aliases, quoting, and schema keywords, and it reports line-level errors with exact line numbers. The ruleset is pinned to a version (yaml-validator@2026-07-19), which matters more than it sounds: a linter whose behaviour drifts between runs is a linter I cannot put in a checklist. Pinning means the same file gets the same report.
The three bugs that actually cost me time
Duplicate keys are the quietest. YAML resolves a repeated key by letting the later one win, so the file parses, the deploy succeeds, and a setting I thought I configured is silently overridden. There is no error from the parser because the document is valid; the mistake is in my intent. A linter that flags the duplicate is the only thing between me and a config that looks right and behaves wrong.
Anchors and aliases are the second. A shared block defined once with &defaults and reused with *defaults is tidy until someone renames the anchor in one place and not the other. The reference now points at nothing, and depending on the parser you get either a confusing error or a subtly different document. Checking that every alias resolves to an anchor that exists is a bounded, mechanical check, and it is exactly the kind of thing I forget to do by hand.
Quoting and the boolean ambiguity are the third family. yes, no, on, and off have meant different things across YAML versions, and a value I intended as a string can arrive as a boolean in a tool that parses with different assumptions. I am not asking the linter to decide what I meant; I am asking it to surface the places where the file is easy to misread, so I can quote the value explicitly and stop relying on a parser's defaults.
Where deterministic lint stops
I want to be precise about the limit, because "validator" invites over-reading. This is a deterministic lint of the config text you paste. It catches structural problems: tabs, indentation, duplicate keys, broken anchor references, quoting traps, schema keywords. It does not tell you whether the config is semantically right for your service. A perfectly lint-clean deployment file can still request the wrong image tag, point at the wrong database, or set a replica count that takes down a dependency. Those are facts about your system, not about the YAML.
It also does not deploy anything, does not resolve remote references, does not execute the config, and does not validate the semantics of a specific platform's schema beyond the keyword checks in the ruleset. Line numbers point at the file you pasted, so if you paste a fragment, that is the scope of the report. It is decision-support for a pre-deploy check, not a live audit of your cluster, a certification that the config is safe, or legal advice about what you are allowed to ship.
If your last config incident was invisible whitespace or a silently overridden key, pasting the file into YAMLValidator before you push is a cheap habit. Then do the part it cannot: read the values and confirm they are the ones you meant.
FAQ
Does it deploy or run my config?
No. It lints the YAML text you paste and reports line-level errors. It does not deploy, execute, or resolve remote references.
Is a clean report proof my config is correct?
No. It is a structural lint. Semantic mistakes like a wrong image tag or database target are outside it, and checking those is still your job.
Why a pinned ruleset?
So the same file produces the same report every run. It is decision-support, not a live audit or a certification of your deployment.
Top comments (1)
The pinned ruleset is doing more work than it gets credit for. "Same file, same report" is what makes a check belong in a checklist at all - a linter whose behavior drifts teaches its users to re-run until green, which is worse than no linter because it converts a gate into a slot machine.
Duplicate keys are the honest villain here: the document is valid, the deploy succeeds, and the parser has nothing to say because the mistake lives in intent, not syntax. That is the family worth automating first, precisely because no human review reliably catches it - the file reads fine.
And the closing boundary is the right one. "Structurally valid" and "right for your system" are different claims, and most checklist tools blur them to sound stronger. Naming the limit is what makes the part it does check believable.