Compare the original digits with the parsed result
Run this synthetic example in a JavaScript console. The original JSON text contains 9007199254740993, but the parsed Number rounds to 9007199254740992. Stringifying later cannot recover the lost digit.
Number.MAX_SAFE_INTEGER is 9007199254740991. Some larger integers happen to be representable, but adjacent integers are no longer all distinguishable. Do not use a successful test with one large value as proof that an identifier range is safe.
const raw = '{"id":9007199254740993}';
const value = JSON.parse(raw);
console.log(value.id); // 9007199254740992
console.log(JSON.stringify(value)); // {"id":9007199254740992}
console.log(Number.isSafeInteger(value.id)); // falsePreserve identifiers before parsing
If an order number, database key or account identifier is not used for arithmetic, agree on a string representation in the API contract. This also preserves leading zeroes. Fix the producing system rather than guessing the original digits after rounding.
BigInt can represent large integers in JavaScript, but JSON does not have a BigInt literal. JSON.stringify on a plain BigInt throws unless you provide a serialization policy. A schema and producer/consumer agreement are still needed.
For payloads you cannot change, use a parser designed to preserve numeric tokens or a supported source-aware parsing technique. An ordinary reviver receiving an already rounded Number cannot restore the original value merely by calling BigInt(value).
const raw = '{"id":"9007199254740993","count":3}';
const value = JSON.parse(raw);
console.log(value.id); // exact string
const exact = BigInt(value.id);
console.log(exact + 1n); // 9007199254740994nCheck a formatting workflow without corrupting evidence
Keep an untouched copy of the source file. Use Text Diff to compare the source with formatted output if necessary, but remember that whitespace changes can make a raw diff noisy. Inspect the numeric fields explicitly.
Do not submit signed or precision-sensitive data to a parse-and-reserialize workflow unless its contract permits changes. Formatting also does not check schema constraints or prove that the content is trustworthy.
For a regression check, test the maximum expected identifier, adjacent values, a leading-zero string and a round trip through every service that handles the payload. Perform arithmetic assertions only after choosing a numeric type with the required range and precision.
References
Use the linked specifications and product documentation to check behavior in your own environment.
Continue troubleshooting
- JSON syntax vs schema validation: format and diagnose JSON
- How to minify JSON
- How to Detect and Recover Lost Shopify Theme Customisations After an Update
- How to Fix Power Platform Deployment Settings and Connection Reference Errors
- How to Fix Power BI Theme JSON Import Errors
- How to Find and Fix JSON Syntax Errors
- How to Compare Two JSON Files with Semantic Diff
- How to Generate TypeScript Interfaces from JSON
- How to Convert Nested JSON to Tabular CSV
- How to Convert Between JSON and YAML
- JWT exp, nbf and iat explained with timestamp examples
- Base64 vs Base64URL: why JWT decoding fails
Related tools
Frequently asked questions
Is this invalid JSON syntax?
No. The precision limitation belongs to the consumer’s number representation.
Does pretty-printing preserve every large integer?
No. A formatter that parses JavaScript Numbers can round values before displaying them.
Can converting a rounded Number to BigInt fix it?
No. The conversion preserves the rounded value, not the original JSON digits.