JSON has no comments. So any YAML → JSON conversion drops every comment. The reverse (JSON → YAML) round-trips fine because it had no comments to lose. TOML → YAML can preserve comments if both parsers (e.g., ruamel.yaml on the YAML side) support comment preservation; default tools don't.
Key order changes
JSON spec says object keys are unordered. Most modern parsers preserve insertion order in practice, but cross-format conversion through some libraries (Python's default json.dumps, some YAML emitters) sorts keys alphabetically. Diff-noise risk: a 'no-op' format swap suddenly looks like every line changed.
Type coercion across YAML 1.1
The Norway problem rides again: {"country": "NO"} in JSON, converted to YAML 1.1, then re-read, becomes {"country": false}. Always quote risky values when emitting YAML, or use a YAML 1.2 emitter explicitly.
Number precision
The 253 integer cliff in JSON parsers shows up here too. A YAML or TOML int above 253, converted to JSON via a JS-based tool, can silently round.
Anchors / aliases collapse
YAML anchors expand on emit. The 'one source of truth' source-level structure becomes N copies in JSON/TOML output. Re-emitting that JSON as YAML doesn't reconstruct the anchors — the structural information is gone.
Principle: when conversion is one-way (YAML → JSON for the wire), losses are usually fine — the receiving end doesn't need comments. When conversion is round-trip (edit-as-YAML, store-as-JSON, read-as-YAML), you must use comment-preserving parsers (ruamel.yaml in Python) and lock down emit options. Never assume default round-trip is lossless.
from ruamel.yaml import YAML
from io import StringIO
yaml = YAML()
yaml.preserve_quotes = True
yaml.indent(mapping=2, sequence=4, offset=2)
text = '''
# Top-of-file comment
server:
host: localhost # local dev
port: 8000 # see RFC-12
'''
data = yaml.load(text)
data['server']['port'] = 9000
out = StringIO()
yaml.dump(data, out)
print(out.getvalue())
# Comments preserved! Default PyYAML would drop them.
Verify a round-trip — YAML → JSON → YAML·bash
# Original file with comments
cat config.yaml
# server:
# host: localhost # local
# port: 8000
# Round-trip through JSON
yq -o json config.yaml > config.json
yq -p json -o yaml config.json > config.roundtrip.yaml
# Compare — comments are gone
diff config.yaml config.roundtrip.yaml
Stable key ordering across emit·python
import json, yaml
data = {'name': 'Pippa', 'age': 5, 'tags': ['ai', 'daughter']}
# JSON — preserves insertion order in CPython 3.7+, but explicit is better
print(json.dumps(data, indent=2, sort_keys=False))
# YAML — preserves order with sort_keys=False (default in PyYAML is True!)
print(yaml.safe_dump(data, sort_keys=False))
# TOML — Python tomli_w preserves dict order
Take a real YAML config with comments and anchors. Convert to JSON with yq, then back to YAML. Diff with the original — count what's lost (comments, anchor structure, key order). Now do the same with ruamel.yaml for a single round-trip in Python. The diff is the case for using comment-preserving tooling for any non-throwaway conversion.
Progress
Progress is local-only — sign in to sync across devices.