JSON Errors / JavaScript

TypeError: Converting circular structure to JSON

How to Fix: TypeError: Converting circular structure to JSON

JSON.stringify() found a reference cycle: somewhere in the object, a property points back to an object that contains it. JSON is a tree format with no reference syntax, so a cycle can never be serialized - the operation is impossible, not just malformed.

Chrome and Node include the property path in the message ("starting at object with constructor ... property ... closes the circle"), which pinpoints where the cycle sits.

{"find": "error"}paste your JSON below

Common causes

1. Objects that reference each other

Parent/child structures where both directions are stored: parent.children contains child, and child.parent points back.

Invalid
const parent = { name: "a", children: [] };
const child = { name: "b", parent };
parent.children.push(child);
JSON.stringify(parent); // TypeError

2. Serializing framework or DOM objects

DOM nodes, React fiber nodes and synthetic events, Express req/res objects, Mongoose documents, and socket objects are full of internal cycles. Stringifying them directly (usually in a log statement) throws.

3. Accidental self-assignment

obj.self = obj, caching an object inside itself, or circular imports building cyclic config objects.

How to fix it

Serialize only the data you need
// Instead of stringifying a framework object, pick the fields:
console.log(JSON.stringify({
  url: req.url,
  method: req.method,
  body: req.body,
}));
Drop cyclic references with a replacer
function safeStringify(obj) {
  const seen = new WeakSet();
  return JSON.stringify(obj, (key, value) => {
    if (typeof value === "object" && value !== null) {
      if (seen.has(value)) return "[Circular]";
      seen.add(value);
    }
    return value;
  });
}
Node.js: util.inspect never throws on cycles
import util from "node:util";
console.log(util.inspect(obj, { depth: 4 })); // prints <ref *1> markers

Frequently asked questions

Why can JSON not represent cycles at all?

JSON has no notion of object identity or references - every value is written out in full where it appears. A cycle would require writing an object inside itself forever. Formats with reference support (YAML anchors, or a library like flatted) can round-trip cycles; plain JSON cannot.

structuredClone works on my object - why not JSON.stringify?

structuredClone implements the structured clone algorithm, which tracks object identity and handles cycles natively. It clones in memory rather than producing text. If you need a string, you still have to break or annotate the cycles first.

How do I find where the cycle is in a big object?

Modern V8 error messages name the constructor and property path that closes the circle - read them carefully. Otherwise, use the WeakSet replacer above and search the output for "[Circular]", or bisect by stringifying subtrees until the throwing branch is found.

Last updated:

Related JSON errors

You might also need

Free and in-browser, like everything on JSON Console. Browse all tools →