by YAMLValidator (LX AI)
YAMLValidator — Catch YAML errors before they break your deploy Use it as decision-support: demo mode works without a live key; live runs require configuration. No fabricated metrics, and no claims for SSO/CSV/Slack unless that surface is actually shipped.
Decision-support only — confirm before you publish or act.
I built YAMLValidator as a thin wrapper around two passes. The first pass runs a fixed lint rule set that checks syntax and structural problems without executing any of your code. The second pass sends each detected problem to a language model that returns a short explanation, the exact line number, and a corrected snippet. The tool returns a JSON report that you can store, diff, or fail a CI job on. Because the model only sees the problematic fragment, there is no risk of leaking unrelated configuration.
When you run the demo mode the model call is skipped and you still get the deterministic output. Live mode requires you to set an API key in the environment; the key is used solely for the explanatory pass and is not stored after the run.
The lint engine is versioned as yaml-validator@2026-07-19. It parses the document with a strict YAML 1.2 parser and then walks the token stream looking for specific patterns. Each rule has a stable ID and a short description that appears in the report.
| Rule ID | Description | Triggering snippet | Suggested fix |
|---|---|---|---|
| INDENT-001 | Tab character found in indentation | key: value | Replace the tab with two spaces |
| DUPKEY-007 | Duplicate key 'server' in mapping | server: prod server: dev |
Remove or rename the duplicate entry |
| ANCHOR-012 | Alias '*ref' points to undefined anchor | *ref | Define an anchor named 'ref' before using it |
| QUOTE-003 | Unquoted string contains a colon | path: src/main:utils | Quote the scalar: "src/main:utils" |
| KEYWORD-005 | Reserved tag !!str used unintentionally | name: !!str John | Remove the tag unless you need explicit typing |
| CTRL-009 | Raw tab inside scalar | message: Hello\tWorld | Escape the tab as \t or use a block scalar |
Each rule runs in a single pass over the parsed tokens, so the runtime grows linearly with the size of the file. The rule set is frozen for a given version; you can pin the version in your CI configuration to avoid surprise changes.
After the lint pass finishes, the tool creates a small payload for each finding: the file path, the line number, the surrounding three lines of context, and the rule ID. This payload is sent to the language model endpoint you have configured. The model is prompted to return:
The model does not see the rest of your repository, only the snippet you provide. This keeps the data boundary clear and lets you run the tool in environments where external network calls are restricted—you can point the endpoint to a local model server if you prefer.
Because the model is used only for explanation, the deterministic lint result is always the source of truth for pass/fail decisions. If the model call fails or returns an empty response, YAMLValidator still emits the lint findings and marks the explanation field as null.
I add YAMLValidator as a step in the pipeline that runs before any deployment or rendering job. The step looks like this in a generic YAML‑based CI:
steps:
- uses: actions/checkout@v4
- name: Run YAMLValidator
env:
MODEL_KEY: ${{ secrets.MODEL_KEY }}
run: |
yamlvalidator --src ./configs --format json --out report.json
# fail the build if any lint error is present
if jq '.results | any(.level == "error")' report.json; then
exit 1
fi
The command line accepts a directory or a list of files. You can optionally pass --demo to skip the model call and rely solely on the lint output. The JSON report contains a top‑level runId that is a UUIDv4 generated at start‑time; you can store this ID alongside your build artifacts for traceability.
If you prefer a binary exit code without parsing JSON, the tool also offers --strict which returns a non‑zero status when any error‑level finding is present, regardless of the model output.
When I work on a feature branch I run YAMLValidator from my terminal to get instant feedback. I keep a small wrapper script that watches for file changes and re‑runs the validator:
#!/usr/bin/env bash
while true; do
fswait -e .yml,.yaml configs/
yamlvalidator --src configs --format human
done
The human formatter prints each finding with a colored label, the line number, and the model explanation if available. Because the tool never executes your configuration, you can safely run it against production‑like files that contain secrets; the secrets remain in your working directory and are not transmitted unless you explicitly enable the model pass and send the snippet to an external endpoint.
If you use an IDE that supports custom tasks, you can bind the validator to a file‑save hook. The task runs in the background and shows problems in the editor’s problem panel, letting you fix indentation or duplicate keys before you even commit.
YAMLValidator does not guarantee that your configuration will run without errors in production. It only catches problems that are detectable through static YAML syntax and the specific rule set we ship. Semantic issues such as referencing a non‑existent service, using an incorrect port number, or violating business‑logic constraints are outside its scope.
The model‑assisted explanation is not a substitute for your own review. The model may produce an inaccurate or incomplete suggestion, especially when the surrounding context is large or when the YAML uses custom tags that the model has not seen during training. You must still read the explanation and decide whether the suggested fix matches your intent.
We do not provide any service‑level uptime guarantees for the model endpoint you choose to configure. If you point the tool at a third‑party API, you are responsible for that service’s availability and any associated costs.
YAMLValidator does not include built‑in SSO integrations, Slack notifications, or bulk CSV export unless those features have been explicitly added to this product build. Any mention of those capabilities in documentation or marketing copy should be treated as a placeholder until the corresponding code is shipped.
Finally, the tool is not a security scanner. While it prevents arbitrary code execution by disallowing the YAML !!php/object tag and similar dangerous constructs, it does not scan for known vulnerabilities in the libraries or services that your configuration references.
I keep a written checklist next to every release that touches this topic. The list is boring on purpose: name the owner, name the evidence artifact, and name the rollback. If a step cannot produce a file, a ticket, or a log line, it is not a step — it is a wish.
| Signal | What to record | Stop-ship? |
|---|---|---|
| Unexpected write or send | Tool name, args, identity | Yes until gated |
| Missing confirmation on destructive action | Call path and bypass | Yes |
| Untrusted text treated as instruction | Source surface and resulting action | Yes for agent reach |
| Scanner clean, judgment open | Deferred items + owner | Only if core path safe |
yamlvalidator helps with the measurable first pass. Architecture choices, legal sign-off, and customer-facing claims still need a human owner. Treat every checklist row as decision support, not a certificate.
When a prospect asks whether the product "covers everything," I answer with the boundary: automated checks catch known patterns; novel chains and policy judgment still need review. That honesty keeps support load down and keeps the blog aligned with what the product actually does.
If you need a second opinion, pair this write-up with the references below and with your own staging reproduction. Do not skip the reproduction step just because a model wrote a confident summary.
Catch YAML errors before they break your deploy
Operators and builders who need a fast first draft or checklist from YAMLValidator.
Yes in explicit Demo mode. Live AI requires a configured key.
No. Outputs are decision-support; you still review before publishing or acting.
Only if those features are implemented in this product build — do not assume them from marketing copy.
Runs may be stored locally under the product's .data/ boundary; treat demos as ephemeral.