Last modified: Apr 25, 2026 By Alexander Williams

Fix Circular Structure JSON Error

Have you ever tried to save an object as JSON and got a scary error? You are not alone. The TypeError: Converting circular structure to JSON is a common JavaScript error. It happens when you try to use JSON.stringify() on an object that references itself.

This article explains what causes this error. You will learn how to spot circular references. We will also show you simple ways to fix it. Let's dive in.

What is a Circular Structure?

A circular structure is an object that points to itself. Imagine a family tree where a person lists their parent, and that parent lists the child as their child. This creates a loop. JavaScript objects can have this kind of loop.

The JSON format cannot handle loops. JSON is a strict text format. It needs a tree structure with no cycles. When JSON.stringify() finds a loop, it throws an error.

Example of the Error

Here is a simple example. We create an object and make it point to itself.


// Create a simple object
let user = {
  name: "Alice",
  age: 30
};

// Make a circular reference
user.self = user;

// Try to convert to JSON
try {
  let json = JSON.stringify(user);
  console.log(json);
} catch (error) {
  console.log(error.message);
}

When you run this code, you will see:


TypeError: Converting circular structure to JSON

The error tells you exactly what is wrong. The object user has a property self that points back to itself. This creates a circle.

Common Causes of Circular References

Circular references often appear in real code. Here are three common situations.

1. Parent-Child Relationships

In data structures like trees or linked lists, nodes often reference each other.


// A node in a linked list
let nodeA = { value: 1 };
let nodeB = { value: 2 };

// Node A points to Node B
nodeA.next = nodeB;
// Node B points back to Node A (circular)
nodeB.prev = nodeA;

// This will cause the error
// JSON.stringify(nodeA);

2. DOM Element References

JavaScript objects sometimes hold references to DOM elements. The DOM itself can have circular references.


let element = document.getElementById('myDiv');
let data = {
  name: "myData",
  element: element
};

// The element object has internal circular references
// JSON.stringify(data); // Error!

3. Self-Referencing Objects in Applications

You might build a configuration object that accidentally points to itself.


let config = {
  name: "appConfig"
};
// Accidentally set the whole config as a property
config.settings = config;

// JSON.stringify(config); // Error!

How to Fix the Error

There are several ways to fix this problem. Choose the method that fits your situation.

Method 1: Remove the Circular Reference

The simplest fix is to delete the circular property before stringifying.


let user = { name: "Bob" };
user.self = user;

// Remove the circular property
delete user.self;

// Now it works
let json = JSON.stringify(user);
console.log(json); // {"name":"Bob"}

Method 2: Use a Replacer Function

The JSON.stringify() method accepts a replacer function. You can use it to skip circular references.


let user = { name: "Charlie" };
user.self = user;

// Replacer function to handle circular references
let seen = new WeakSet();
let json = JSON.stringify(user, function(key, value) {
  if (typeof value === "object" && value !== null) {
    if (seen.has(value)) {
      return; // Skip circular reference
    }
    seen.add(value);
  }
  return value;
});

console.log(json); // {"name":"Charlie"}

This approach is clean. It keeps your original object intact. The WeakSet tracks visited objects.

Method 3: Use a Library

Libraries like lodash have a cloneDeep function. It can handle circular references.


// You need to install lodash first
// npm install lodash

const _ = require('lodash');

let user = { name: "Diana" };
user.self = user;

// Clone deeply to break the reference
let cleanUser = _.cloneDeep(user);

// Now stringify the clone
let json = JSON.stringify(cleanUser);
console.log(json); // {"name":"Diana"}

This method is safe. It creates a new object without cycles.

Method 4: Use the toJSON Method

You can define a toJSON method on your object. This method controls how the object is serialized.


let user = {
  name: "Eve",
  toJSON: function() {
    // Return only the properties you want
    return {
      name: this.name
    };
  }
};

// Even if you add a circular reference
user.self = user;

// The toJSON method prevents the error
let json = JSON.stringify(user);
console.log(json); // {"name":"Eve"}

How to Debug Circular References

If you don't know where the circular reference is, use a debugging tool. The replacer function from Method 2 can log the keys.


let data = { a: 1 };
data.b = data;

let seen = new WeakSet();
try {
  let json = JSON.stringify(data, function(key, value) {
    if (typeof value === "object" && value !== null) {
      if (seen.has(value)) {
        console.log("Circular reference found at key:", key);
        return;
      }
      seen.add(value);
    }
    return value;
  });
} catch (error) {
  console.log("Error:", error.message);
}

This logs the key where the circle starts. You can then fix it.

Preventing the Error in the Future

Here are some best practices to avoid this error.

  • Be careful with object assignments. Do not assign an object to one of its own properties.
  • Use immutable data patterns. Create new objects instead of mutating existing ones.
  • Validate data before serialization. Check for circular references using a utility function.
  • Use a custom serializer. For complex data, write a function that safely handles cycles.

If you work with Python and encounter similar type errors, check out our guide on Python TypeError: Causes and Fixes. It covers many common type errors in Python.

Conclusion

The TypeError: Converting circular structure to JSON is frustrating but easy to fix. The error happens when an object references itself. You can remove the circular reference, use a replacer function, clone the object, or use a toJSON method.

Always check for loops before calling JSON.stringify(). This saves time and prevents crashes. With the examples in this article, you can now handle this error like a pro.

For more help with JavaScript errors, explore our Python TypeError: Causes and Fixes article. It gives you a broader view of type errors and how to solve them.