JSON troubleshooting
TypeError: Do not know how to serialize a BigInt
Serialize BigInt values without losing precision. Choose strings, JSON.rawJSON or a replacer, and read large integer IDs back safely in JavaScript.
What the error means
JSON.stringify has no built-in representation for BigInt, so it throws instead of guessing. JSON text itself allows integers of any length, but a JavaScript number holds integers exactly only up to 9007199254740991 (Number.MAX_SAFE_INTEGER). Converting a BigInt to a number can silently change it. The error usually comes from 64-bit integer database columns that a driver or ORM returns as BigInt, from blockchain libraries, or from values written with the n suffix.
Exact messages by runtime
Messages depend on the input and runtime version. Node and Python rows were reproduced locally. Other rows cite official documentation or source. Rows marked as fragments or templates preserve the source wording and are not complete exception transcripts. Browsers and libraries may append location details.
| Runtime | Message | Input and evidence |
|---|---|---|
| JavaScript / V8 | TypeError: Do not know how to serialize a BigInt | JSON.stringify({ id: 1n })Reproduced in Node.js 24.21.0 |
| Firefox | TypeError: BigInt value can't be serialized in JSON | The same inputOfficial SpiderMonkey message, Firefox 158 source |
| Safari / JavaScriptCore | TypeError: JSON.stringify cannot serialize BigInt. | The same inputJavaScriptCore source (WebKit tag webkitgtk-2.54.1) |
| JavaScript, reading a large integer | No error: the value becomes 9007199254740992 | JSON.parse('{"id":9007199254740993}').idReproduced in Node.js 24.21.0 |
Causes you can reproduce
A database column arrives as BigInt
Drivers and ORMs can map 64-bit integer columns to BigInt; the Prisma documentation shows this exact error for its BigInt fields. The object looks normal until it is serialized.
const row = { id: 9007199254740993n, name: 'Ada' }; // for example, a BIGINT column
JSON.stringify(row);
// TypeError: Do not know how to serialize a BigIntA framework serializes the response for you
Response.json, res.json and similar helpers call JSON.stringify internally, so the stack trace points into the framework rather than your code.
Response.json({ id: 1n });
// TypeError: Do not know how to serialize a BigIntConverting to Number changes the value
Number() makes the error go away, but integers above Number.MAX_SAFE_INTEGER round to the nearest value a double can hold.
console.log(Number(9007199254740993n)); // 9007199254740992How to fix it
- Find the field that holds a BigInt by checking typeof value === 'bigint' for the values you serialize.
- Agree on a wire format with the receiver. A decimal string is the most portable form for IDs; a JSON number is valid, but many clients read it as a double.
- Convert at the serialization boundary with a replacer, a toJSON method on your own class, or an output object.
- Read large integers back as strings or BigInt; do not let JSON.parse turn them into numbers first.
Send BigInt values as strings
Every JSON parser can read a string without rounding it. Convert back with BigInt() where you need arithmetic.
const row = { id: 9007199254740993n, name: 'Ada' };
const text = JSON.stringify(row, (key, value) =>
typeof value === 'bigint' ? value.toString() : value);
console.log(text); // {"id":"9007199254740993","name":"Ada"}
console.log(BigInt(JSON.parse(text).id) === row.id); // trueWrite an exact JSON number with JSON.rawJSON
MDN lists JSON.rawJSON as Baseline 2025, and Node.js 24 supports it. The receiver must also read the number without rounding.
const row = { id: 9007199254740993n };
const text = JSON.stringify(row, (key, value) =>
typeof value === 'bigint' ? JSON.rawJSON(value.toString()) : value);
console.log(text); // {"id":9007199254740993}Read a large integer without rounding
The third reviver argument, context, holds the source text of each primitive value. Check browser support on MDN before relying on it in browser code.
const text = '{"id":9007199254740993}';
console.log(JSON.parse(text).id); // 9007199254740992
const data = JSON.parse(text, (key, value, context) =>
key === 'id' ? BigInt(context.source) : value);
console.log(data.id); // 9007199254740993nFrequently asked questions
Does JSON support big integers?
The JSON grammar allows any number of digits. RFC 8259 warns that many implementations use IEEE 754 double precision, so integers outside the range -(2^53)+1 to (2^53)-1 may not be read exactly. Send IDs as strings when you do not control the receiver.
Should I add BigInt.prototype.toJSON?
It works, but it changes JSON.stringify for every BigInt in the process, including inside libraries, and the receiver still gets a string. A replacer at the call site keeps the decision local.
Why not convert with Number()?
Number() rounds integers above 9007199254740991. 9007199254740993n becomes 9007199254740992, which is a different ID.
Can I inspect large numbers without rounding?
Tool Kumar's viewer keeps each number's original digits, so 64-bit IDs in a JSON document are shown exactly. JSON.parse in your own code still needs one of the approaches above.
Related errors and tools
- TypeError: Converting circular structure to JSON
- TypeError: Object of type … is not JSON serializable
- "undefined" or "[object Object]" is not valid JSON
- All JSON error guides
- JSON syntax reference
- Inspect large numbers without rounding in the JSON viewer
Standards and diagnostic sources
RFC 8259 and ECMA-404 define JSON syntax. Diagnostic wording belongs to the parser. The table links each cited message to its source.