In 2019 a developer reported a bug that has been quietly breaking config files ever since. Their country list had an entry for Norway, country code NO. After a trip through YAML, Norway had vanished — and in its place was the boolean false.

This is the Norway problem, and it is not a parser bug. It is YAML working exactly as designed. YAML infers the type of an unquoted value from how the text looks, and in the widely used YAML 1.1 rules, no is a perfectly valid way to write "false" — along with yes, on, and off.

JSON never has this problem, because JSON puts quotes around every string. The moment you convert JSON to YAML, those quotes come off — and any value that looks like something else quietly becomes that something else. This guide covers exactly which values are at risk, how structure translates, and what a safe conversion looks like.

The Norway Problem

Here is the failure in full. This JSON is unambiguous — every value is a string:

{ "country": "NO", "shipping": "yes", "debug": "off" }

Converted carelessly, the quotes disappear and a YAML 1.1 parser reads all three as booleans:

country: NO # parsed as false shipping: yes # parsed as true debug: off # parsed as false

Nothing errors. Your file loads, your pipeline runs, and somewhere downstream a country code has become False. The fix is simply to keep the quotes, and a conversion that understands YAML does it for you:

country: "NO" shipping: "yes" debug: "off"
Why this still matters in 2026 YAML 1.2 narrowed booleans to just true and false. But plenty of tooling still follows the 1.1 rules — PyYAML, which sits under Ansible and countless Python scripts, treats yes, no, on, and off as booleans by default. Quoting costs nothing and works under both versions.

Why YAML Guesses Types at All

The difference between the two formats comes down to one design choice.

JSON is explicit. A string is anything inside double quotes. "28" is a string, 28 is a number, and there is never a question about which is which.

YAML is implicit. Quotes are optional, so the parser has to infer the type from the shape of the text. 28 becomes a number, true becomes a boolean, null and ~ become null, and everything else falls back to being a string.

That inference is what makes YAML pleasant to write by hand — no punctuation for the common case. It is also exactly why converting into YAML needs care: the conversion has to notice which strings would be misread once their quotes are gone, and put them back.

Which Values Must Stay Quoted

Four categories of string need protection. CodBolt's converter adds the quotes automatically, but these are worth recognising in any YAML you review.

1. Boolean and null lookalikes

The classic case, matched case-insensitively so NO, No, and no are all caught:

{ "a": "NO", "b": "yes", "c": "Off", "d": "TRUE", "e": "null", "f": "~" } a: "NO" b: "yes" c: "Off" d: "TRUE" e: "null" f: "~"

2. Numbers stored as strings

This one bites hardest on identifiers with leading zeros, which lose them silently:

{ "zip": "10001", "id": "007", "minor": "2.1", "version": "2.1.0" } zip: "10001" id: "007" minor: "2.1" version: 2.1.0

Note the last line. 2.1.0 has two dots, so it is not a valid YAML number and stays a string on its own — no quotes needed. 2.1 would become the number 2.1, so it keeps them.

3. Strings with YAML punctuation

A colon starts a key, a hash starts a comment, and brackets and braces start inline collections. Any string containing them gets quoted so it stays a value:

{ "ports": "80:80", "note": "50% #1 choice" } ports: "80:80" note: "50% #1 choice"

4. Empty strings and edge whitespace

An empty string with no quotes is indistinguishable from no value at all, and leading or trailing spaces would be trimmed away. Both keep their quotes:

{ "blank": "", "padded": " spaced " } blank: "" padded: " spaced "
Real values stay unquoted Quoting only applies to strings that would be misread. A genuine JSON number stays age: 28, a genuine boolean stays active: true, and null stays null. The output reads like handwritten YAML, not like JSON with the braces removed.

How Structure Translates

Once quoting is handled, the structural mapping is refreshingly direct — YAML and JSON describe the same shapes.

Objects become indented blocks. Each key sits on its own line, and nesting is expressed by indenting two more spaces:

{ "services": { "web": { "image": "nginx", "ports": ["80:80"] } } } services: web: image: nginx ports: - "80:80"

Arrays become sequences. Every item gets its own line beginning with a dash:

{ "skills": ["JavaScript", "Python"] } skills: - JavaScript - Python

For an array of objects, the first key shares the dash line and the rest line up underneath it. This is the idiomatic YAML layout and what tools like Docker Compose and GitHub Actions expect:

{ "books": [ { "title": "Dune", "year": 1965 }, { "title": "Neuromancer", "year": 1984 } ] } books: - title: Dune year: 1965 - title: Neuromancer year: 1984

Empty collections stay inline. There is nothing to indent, so an empty array is written [] and an empty object {} — both valid YAML, using its JSON-compatible flow style:

{ "tags": [], "meta": {}, "note": null, "count": 0 } tags: [] meta: {} note: null count: 0

Indentation Is the Syntax

In JSON, indentation is decoration — you can minify a file to one line and it still means the same thing. In YAML, indentation is the structure. Change it and you change the data.

Two rules follow from that, and both catch people out when they hand-edit converted files:

  • Tabs are not allowed for indentation. YAML requires spaces. A stray tab is a parse error, not a style issue — which is why editors configured for tabs cause so much YAML grief.
  • Sibling keys must align exactly. One extra space turns a sibling into a child, changing the shape of your data without any error message.

A converter sidesteps both problems by emitting consistent two-space indentation throughout. The risk starts when you edit the result by hand — so if a converted file suddenly misbehaves, check the indentation of the lines you touched first.

Rule out the JSON first If nothing converts at all, suspect the input before you suspect YAML. Broken JSON never reaches the YAML stage, so the error you are chasing is upstream. Run it through the JSON Formatter to locate the bad line — trailing commas and single quotes cause most of these — or read our breakdown of formatting, minifying, and validating.

How to Convert JSON to YAML, Step by Step

  1. Open the JSON to YAML converter.
  2. Drop your JSON in on the left — paste it, or hit Upload for a file of up to 100 MB.
  3. Hit Convert. The YAML lands on the right, indented two spaces per level, with risky strings already wrapped in quotes.
  4. Read the quotes. Each one marks a value that would have changed type without them, which makes the output double as a list of the fields worth checking.
  5. Grab it with Copy, or hit Download for a data.yaml file ready to commit.

The Sample button loads a record with a list and a nested block in it, which is enough to show how a real config file will come out.

Nothing leaves your machine during any of this — worth knowing, since config files are exactly the kind of file that tends to hold connection strings and API keys.

Going further with the same data YAML is the right target for config files and pipelines. If the destination is a partner system instead, converting JSON to XML covers that path, and JSON to CSV is the route to a spreadsheet.
Try it now — CodBolt JSON to YAML

Config-ready output: real sequences, automatic quoting, nothing uploaded.

Open Tool