Fix: undefined, NaN, and Infinity in JSON
JavaScript has values that make total sense in code but are simply not part of the JSON standard. When they end up in a value you try to serialise or parse as JSON, you get either a silent data loss or a parse error — depending on which direction the conversion is going.
The Problem: Not All JS Values Are Valid JSON
JSON only supports these value types: string, number (finite decimal), object, array, true, false, and null. The following are all illegal in JSON:
| Value | Valid JSON? | JSON.stringify() behaviour | Recommended replacement |
|---|---|---|---|
| undefined (object key) | No | Key is silently omitted | null or omit key |
| undefined (array element) | No | Converted to null | null |
| NaN | No | Converted to null | null |
| Infinity | No | Converted to null | null or a large number |
| -Infinity | No | Converted to null | null or a large negative number |
| Symbol | No | Key omitted / value → undefined | Convert to string first |
| BigInt | No | Throws TypeError | Convert to string or number |
| Function | No | Omitted | Do not serialise functions |
JSON.stringify() Behaviour in Detail
// 1. undefined as object property — silently omitted
JSON.stringify({ a: 1, b: undefined });
// → '{"a":1}' ← 'b' is gone!
// 2. undefined in array — becomes null
JSON.stringify([1, undefined, 3]);
// → '[1,null,3]'
// 3. NaN and Infinity — both become null
JSON.stringify({ score: NaN, limit: Infinity });
// → '{"score":null,"limit":null}'
// 4. Calling JSON.stringify(undefined) directly
JSON.stringify(undefined);
// → undefined (not the string "undefined", actual undefined)
// 5. BigInt — throws
JSON.stringify({ id: 9007199254740993n });
// TypeError: Do not know how to serialize a BigIntHow to Detect Silent Data Loss
The silent conversion is the dangerous part. Use a custom replacer to surface these values explicitly:
function strictStringify(value, indent = 2) {
return JSON.stringify(
value,
(key, val) => {
if (val === undefined) throw new TypeError(`Key "${key}" is undefined`);
if (typeof val === "number" && !isFinite(val)) {
throw new TypeError(`Key "${key}" has non-finite value: ${val}`);
}
return val;
},
indent
);
}
// Now errors are explicit, not silent
strictStringify({ score: NaN });
// TypeError: Key "score" has non-finite value: NaNReceiving Invalid JSON with These Values
If you receive a string like {"score": NaN} from a server or legacy system that emits pseudo-JSON, JSON.parse() will throw. The only fix is to sanitise the string before parsing:
function sanitizeJSON(str) {
// Replace bare NaN, Infinity, -Infinity with null
return str
.replace(/:\s*NaN/g, ": null")
.replace(/:\s*-?Infinity/g, ": null")
.replace(/:\s*undefined/g, ": null");
}
const raw = '{"score": NaN, "limit": Infinity}';
JSON.parse(sanitizeJSON(raw));
// → { score: null, limit: null }Note: string replacement is fragile. A proper parser that handles JSON5/pseudo-JSON is safer for production use.
Frequently Asked Questions
Why are undefined, NaN, and Infinity not valid JSON?▾
The JSON specification (RFC 8259) only defines six value types: string, number, object, array, true/false, and null. undefined is a JavaScript concept, not part of any data format. NaN and Infinity are IEEE 754 floating-point special cases that JSON's number grammar cannot represent — a JSON number must match a finite decimal pattern.
What does JSON.stringify do with undefined values?▾
JSON.stringify silently omits object properties whose value is undefined. If undefined appears as an array element, it is converted to null. If you call JSON.stringify(undefined) directly, it returns undefined (not a string).
What does JSON.stringify do with NaN and Infinity?▾
JSON.stringify converts both NaN and Infinity (including -Infinity) to the JSON value null. This means data can be silently lost. Always sanitise NaN/Infinity before serialising if you need to preserve the distinction.
How can I detect when JSON.stringify silently drops or changes values?▾
Use a custom replacer function. Return a sentinel string like '__UNDEFINED__' or throw an error when you encounter undefined, NaN, or Infinity so the loss is explicit rather than silent.
What is the best way to represent "no value" in JSON?▾
Use null. It is the only JSON value that explicitly represents the absence of a meaningful value. Alternatively, omit the key entirely if absence and null have the same semantics in your API.
More JSON Error Guides
If jsondecode.com saved you time, share it with your team
Free forever. No ads. No sign-up. Help other developers find it.