jsondecode.com logo

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:

ValueValid JSON?JSON.stringify() behaviourRecommended replacement
undefined (object key)NoKey is silently omittednull or omit key
undefined (array element)NoConverted to nullnull
NaNNoConverted to nullnull
InfinityNoConverted to nullnull or a large number
-InfinityNoConverted to nullnull or a large negative number
SymbolNoKey omitted / value → undefinedConvert to string first
BigIntNoThrows TypeErrorConvert to string or number
FunctionNoOmittedDo 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 BigInt

How 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: NaN

Receiving 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.

If jsondecode.com saved you time, share it with your team

Free forever. No ads. No sign-up. Help other developers find it.