YAML gotchas: the Norway problem and other silent traps
YAML's convenience comes from implicit typing, which is also where it bites — countries turning into false, version numbers losing digits, and times becoming integers. The traps and how to avoid them.
YAML is pleasant to write — no braces, no quotes, just indentation and values. That convenience comes from one feature: it guesses the type of an unquoted value. Most of the time the guess is right. The rest of the time it silently turns your data into something else, and because it's silent, you find out in production. The famous example is a country code that becomes a boolean, but it's one instance of a broader pattern worth recognizing.
Implicit typing is the root cause
When YAML sees an unquoted scalar, it tries to interpret it: 123
becomes an integer, true becomes a boolean, null becomes null, and
so on. You never asked for a type — YAML inferred one from the shape of
the text. This is what lets you write count: 3 without quotes, and
it's also what causes every trap below. The fix for all of them is the
same — quote the value — but you have to know when to reach for the
quotes.
The Norway problem
The headline case: a list of country codes.
countries:
- NO # Norway
- SE # Sweden
- FR # France
In the YAML 1.1 spec, NO is a boolean false — along with YES,
ON, OFF, TRUE, and their case variants. So Norway silently
becomes false, and a parser hands your application a boolean where it
expected a string. The same logic turns a chemistry list's NO (nitric
oxide) or a user's initials into booleans. Quoting — "NO" — is the
fix.
YAML 1.2 narrowed booleans to just true/false, but many parsers
still default to 1.1 behavior, so you can't assume you're safe. Treat
two-letter all-caps strings as needing quotes.
Version numbers and the sexagesimal trap
Two more that come from numeric inference:
version: 1.20parses as the float1.2— the trailing zero is gone, and1.20 == 1.2is now true when you needed them distinct. Version strings should always be quoted:version: "1.20".time: 22:30can be read as a base-60 (sexagesimal) integer in YAML 1.1:22*60 + 30 = 1350. A field you meant as a clock time becomes a meaningless integer. Quote it.
Leading zeros and the octal surprise
A value like id: 0755 may be interpreted as octal, giving you
493 in decimal. Phone numbers, zip codes, and zero-padded IDs all lose
their leading zeros or get reinterpreted. As with CSV, anything where
the leading zero is significant must be a quoted string.
Other sharp edges
- Tabs are illegal for indentation. YAML requires spaces; a stray tab is a parse error, and editors that insert tabs cause confusing failures.
- Indentation is the structure. A misaligned key silently becomes a child of the wrong parent or a sibling you didn't intend — valid YAML, wrong data.
- Anchors and merge keys (
&,*,<<) are powerful but make documents hard to read and behave differently across parsers; use them sparingly.
The rule that prevents most of this
When in doubt, quote strings that could be mistaken for another
type — booleans-by-accident (NO, YES, ON), version numbers,
times, and zero-padded numbers. You lose nothing by quoting a value
that didn't need it, and you avoid every trap above. For config that's
mostly strings and identifiers, the quoting discipline matters more than
it does for hand-tuned numeric files.
To catch these before they ship, our YAML validator
parses your document in the browser and surfaces structure and errors,
so you can see whether NO came through as a string or a boolean. If
you're still deciding whether YAML is even the right format for your
case, JSON vs YAML weighs the footguns of each
against where each one fits.