YAML lets you write most strings without quotes, which is part of its appeal. The price is that the parser must decide what each plain value means, and sometimes it decides differently from what you intended. Knowing the traps in advance saves some long debugging sessions.
How implicit typing works
When a YAML parser reads an unquoted scalar, it resolves its type from a set of patterns: if it looks like an integer, it is an integer; if it looks like a boolean or null, it is one of those; otherwise it is a string. Quoting a value turns off the guessing and makes it a string.
The rules depend on the YAML version and on the library. YAML 1.1, which many tools still follow, recognises a wide set of boolean spellings. YAML 1.2 narrowed the core schema to true and false only. Libraries differ in which version they implement, and some, such as many for Python, historically followed 1.1 behaviour, which is why the same file can behave differently across tools.
The Norway problem
In YAML 1.1, the following words are all booleans, in any of these cases: y, Y, yes, Yes, YES, n, N, no, No, NO, true, True, TRUE, false, False, FALSE, on, On, ON, off, Off, OFF.
So a list of country codes:
countries:
- GB
- NO
- SE
parses the Norwegian code NO as boolean false in a 1.1 parser. The fix is to quote it: "NO".
Version numbers
python: 3.10
Parsed as a number, 3.10 becomes 3.1, so a CI configuration that asked for Python 3.10 may select 3.1 or fail. Write python: "3.10". A version like 1.2.3 has two dots and is a string, but 1.10 and 2.0 are numbers.
Numbers that look like something else
- Leading zeros. In YAML 1.1,
0755is an octal integer, so it means 493 decimal. YAML 1.2 changed octal to0o755. If you mean the string, quote it, and for file permissions follow the tool's documentation. - Sexagesimal numbers. YAML 1.1 reads
1:30as the base-60 number 90. Quote times, such as"1:30". - Underscores and exponents.
1_000may be read as 1000, and1e3as a float, depending on version. - Special floats.
.inf,-.infand.nanare floating-point values.
Dates and times
YAML has a timestamp type in 1.1 that many libraries support. A bare 2025-04-03 may be parsed into a date object rather than a string, which then serialises differently or fails a string comparison. Quote it if you want text.
Null and empty values
null, Null, NULL, ~ and an empty value all mean null. A key with nothing after the colon has the value null, not an empty string. Use "" for an empty string.
Strings that need quotes
- Values containing
:or# - Values starting with
*,&,!,|,>,%,@, a backtick,-followed by a space, or a quote character - Anything that could be a number, boolean, null or date but should be text: IDs, versions, zip codes, country codes, phone numbers, times
- Leading or trailing spaces you want kept
Single vs double quotes
Single-quoted strings are literal; the only escape is doubling a single quote ('it''s'). Double-quoted strings allow escape sequences such as \n and \" and Unicode escapes.
A defensive habit
If a value is an identifier, a version, a code or a date, quote it. The few extra characters remove a whole class of bugs. For the biggest protection, validate parsed output with a schema, since a syntax check cannot know what you meant.
Check how your file parses
Docento's Text & Markdown Editor checks that a .yml or .yaml file is syntactically valid, which catches structural errors. It cannot tell you how a particular tool will type a value, so test with the tool that will read the file.
Takeaway
YAML infers types from unquoted values, which turns NO into false, 3.10 into 3.1 and 1:30 into 90 in some parsers. Quote identifiers, versions, codes, times and dates, and test with the parser that will actually read the file.