BlogDeveloper

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.20 parses as the float 1.2 — the trailing zero is gone, and 1.20 == 1.2 is now true when you needed them distinct. Version strings should always be quoted: version: "1.20".
  • time: 22:30 can 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.