Does anything throw on bad input?

Fson::load and the fson-check tool never throw on malformed FSON. Errors are collected (LoadResult::errors, each with file:line:col) and a partial document is still produced. Within the model, at() / atPath() throw std::out_of_range for a missing member; the find* / get* / as* forms return nullptr or a fallback instead.

Why is my ---prefixed member missing from queries?

That is what -- is for — see Disabled members. It is preserved and written back; use the member API (memberCount / getMember + isDisabled()) to see it.

Does 1.50 really stay 1.50?

Yes. Number keeps the original lexeme alongside the parsed double. 0xFF stays 0xFF, 1e3 stays 1e3, Infinity stays Infinity. setValue() regenerates the lexeme via std::to_chars.

64-bit integers?

asInteger() goes through double, so an integer value beyond 2^53 keeps its exact lexeme on round-trip but loses precision when you read it as an integer. Treat very large integers as strings if you need exactness.

Is it thread-safe?

A Document is a plain mutable object — no internal locking. Load and own it per thread, or guard shared access yourself. Fson::load / Fson::save on distinct files are independent.

Can I feed FSON to jq?

fson-check --json config.fson | jq '…'. --json produces strict JSON (comments gone, keys quoted). Use --json --keep to turn -- members into ordinary data first.

Is every JSON file valid FSON?

Yes. And almost every JSON5 file too — the two exceptions are nested block comments and the bare-key grammar.

.fson or .json?

Either. The parser does not look at the extension. .fson signals to humans and to editors (see Tools › Editor support) that the file uses FSON features; .json is fine for a file that stays within plain JSON.

Where is the C++ API reference?

The narrative one is the Reference Manual; the exhaustive generated one is /api.