Check that YAML parses, then print it back with consistent indentation and quoting. YAML forbids tabs for indentation, so a tab stops the parse and the error gives the line and column where it sits. Files with several documents separated by --- are handled one document at a time.
name: checkout-api
version: "1.20"
on: yes
replicas: 3
env:
LOG_LEVEL: debug
REGION: ap-southeast-1
features: [coupons, gift-cards]
command:
- npm
- run
- start name: checkout-api
version: '1.20'
'on': 'yes'
replicas: 3
env:
LOG_LEVEL: debug
REGION: ap-southeast-1
features:
- coupons
- gift-cards
command:
- npm
- run
- start
Look at on: yes. It comes back as
'on': 'yes', quoted on both sides. The
parser follows YAML 1.2, where those are ordinary
strings, but it quotes them on output so a YAML 1.1
parser reading the file later does not turn them into
booleans. Many CI systems still use 1.1 parsers. This is
the Norway problem: in 1.1 the country code
NO parses as false.
Quote any value that must stay text.
Write version: 1.20 without quotes and it
is a number, so it comes back as 1.2 and
the trailing zero is gone. Nothing warns you, because as
far as YAML is concerned nothing went wrong. Versions,
phone numbers, zip codes and IDs all need quotes, which
is why the example above quotes version in
the input.
Comments are not part of the parsed document. The formatter parses your YAML and prints the result, so anything the parser discarded is gone.
On a heavily commented manifest, use this to find the error, then fix the indentation by hand in your editor.
Resolved and expanded. The output means the same thing but no longer shares structure, so it is longer and easier to read.
Preserved by default. Turn on Sort keys for alphabetical order, which helps when you diff two config files.
This tells you the indentation is wrong, that a tab sits
where YAML forbids one, or that a key is duplicated. It
does not know whether runs-on is a real
GitHub Actions field or whether your Kubernetes
Deployment is missing a selector. For that,
use actionlint, kubeconform or
the schema support in your editor.
# yamllint checks style and syntax
pip install yamllint
yamllint -d relaxed k8s/
# yq is jq for YAML: query, edit and reformat
yq '.spec.replicas = 5' deployment.yaml
yq -i '.image = "app:2.4.0"' deployment.yaml
# Schema validation, which yamllint does not do
pip install check-jsonschema
check-jsonschema --builtin-schema vendor.github-workflows .github/workflows/*.yml
# Kubernetes manifests specifically
kubeconform -strict deployment.yaml import yaml
# safe_load, never load: plain load can construct arbitrary Python objects
# from a crafted file, which is a remote code execution bug waiting to happen
with open("config.yaml") as f:
config = yaml.safe_load(f)
print(yaml.dump(config, default_flow_style=False, sort_keys=False, indent=2))
# To keep comments through a round trip, use ruamel.yaml instead
# pip install ruamel.yaml
from ruamel.yaml import YAML
ry = YAML()
ry.preserve_quotes = True
data = ry.load(open("config.yaml"))
ry.dump(data, open("config.yaml", "w")) yaml.load without a safe loader can construct arbitrary Python objects from the file, which makes it a well-known security hole. Use safe_load.
// npm i js-yaml
const yaml = require("js-yaml");
const fs = require("node:fs");
const config = yaml.load(fs.readFileSync("config.yaml", "utf8"));
console.log(yaml.dump(config, { indent: 2, lineWidth: -1, noRefs: true }));
// Multi-document files, separated by ---
const docs = yaml.loadAll(fs.readFileSync("manifests.yaml", "utf8"));
console.log(docs.length); Write a fragment as JSON when YAML guesses its type wrong. YAML 1.2 is a superset of JSON, so a JSON object pasted into a YAML file is valid YAML. Inside a JSON-style fragment every string is quoted, which removes the type guessing for those values.
This tool follows the specifications below. Read them when you need the exact normative wording, for example to settle an edge case between two implementations.
It parses the YAML and prints it again with consistent indentation, consistent quoting and block style for sequences. Words like on, yes and no come back quoted, so a YAML 1.1 parser reading the file later does not read them as booleans. A tab used for indentation is a syntax error in YAML, so the formatter reports it instead of converting it.
No. Comments are not part of the parsed document, so reformatting drops them. On a heavily commented Kubernetes manifest, use the tool to find the error, then fix the indentation by hand.
Because unquoted, 1.20 is a number, and 1.20 and 1.2 are the same number. The formatter cannot restore the zero: by the time it sees the value, the zero is gone. Quote anything that must stay text, including versions, zip codes and phone numbers.
It checks the syntax, not the schema. It reports wrong indentation or a duplicated key, but it does not know whether runs-on is a real field. Use kubeval, kubeconform or actionlint for the schema.
Indentation, usually a tab that an editor inserted. After that comes a colon inside an unquoted string, which turns one value into an accidental nested mapping.
To move between formats, YAML to JSON and JSON to YAML handle both directions. For comparing two manifests, the diff checker works on the text and the JSON diff on the parsed structure.