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.

RuntimeMessageInput and evidence
JavaScript / V8TypeError: Do not know how to serialize a BigIntJSON.stringify({ id: 1n })
Reproduced in Node.js 24.21.0
FirefoxTypeError: BigInt value can't be serialized in JSONThe same input
Official SpiderMonkey message, Firefox 158 source
Safari / JavaScriptCoreTypeError: JSON.stringify cannot serialize BigInt.The same input
JavaScriptCore source (WebKit tag webkitgtk-2.54.1)
JavaScript, reading a large integerNo error: the value becomes 9007199254740992JSON.parse('{"id":9007199254740993}').id
Reproduced 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.

JAVASCRIPT
const row = { id: 9007199254740993n, name: 'Ada' }; // for example, a BIGINT column
JSON.stringify(row);
// TypeError: Do not know how to serialize a BigInt

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

JAVASCRIPT
Response.json({ id: 1n });
// TypeError: Do not know how to serialize a BigInt

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

JAVASCRIPT
console.log(Number(9007199254740993n)); // 9007199254740992

How to fix it

  1. Find the field that holds a BigInt by checking typeof value === 'bigint' for the values you serialize.
  2. 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.
  3. Convert at the serialization boundary with a replacer, a toJSON method on your own class, or an output object.
  4. 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.

JAVASCRIPT
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); // true

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

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

JAVASCRIPT
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); // 9007199254740993n

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

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.