BabylonJS/Babylon.js · error
Circular dependency detected!
Error message
Circular dependency detected!
What it means
DependencyGraph.walk performs a topological sort: it repeatedly visits elements whose dependencies have all been satisfied. If elements remain in _list after the traversal completes, some form of cycle (or dependency on a never-added element) prevents ordering, so it logs the remaining set and throws this error.
Source
Thrown at packages/dev/smartFilters/src/optimization/dependencyGraph.ts:93
const requiredBy = this._requiredBy.get(element);
if (requiredBy) {
for (const dependingElement of requiredBy) {
const dependencies = this._dependOn.get(dependingElement);
if (dependencies) {
dependencies.delete(element);
if (dependencies.size === 0) {
toVisit.push(dependingElement);
}
}
}
}
}
if (this._list.size > 0) {
Logger.Error(JSON.stringify(this._list));
throw new Error("Circular dependency detected!");
}
}
}
View on GitHub (pinned to 0592b347b8)
Solutions
- Inspect the JSON logged by Logger.Error right before the throw — it lists the elements stuck in the cycle.
- Remove the cyclic connection/dependency between the reported elements.
- Ensure every element passed to addDependency was first registered with addElement.
- If walk() is called on a shared graph, note it mutates state — build a fresh graph for each walk.
Example fix
// before graph.addDependency(a, b); graph.addDependency(b, a); // cycle // after graph.addDependency(a, b); graph.addDependency(b, c); // acyclic chain
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify no element depends on an unregistered element before walking
for (const [el, deps] of dependOnPairs) {
if (!registered.has(el) || !deps.every(d => registered.has(d))) {
throw new Error("Dependency on unregistered element");
}
} Type guard
null
Try / catch
try {
graph.walk(processElement);
} catch (e) {
if (e.message === "Circular dependency detected!") {
// Logger.Error already dumped the stuck elements; inspect that set to locate the cycle
console.error("Filter graph contains a feedback loop; check connections between logged blocks");
} else throw e;
} Prevention
- Design filter graphs without feedback loops (no connection path from a block back into itself).
- Register every element with addElement before calling addDependency.
- Build a fresh DependencyGraph for each walk — walk mutates the graph.
- Check the Logger.Error JSON output to identify the exact cyclic blocks.
When it happens
Trigger: Calling walk() on a graph where addDependency created a cycle (A depends on B, B depends on A), or where an element was given a dependency via addDependency but that dependency was never added via addElement, so it can never be satisfied/visited.
Common situations: Optimizer graph construction on a filter whose block connections form a feedback loop; building a custom runtime graph with a dependency on a node that was never registered; a bug in custom block dependency wiring.
Related errors
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/a013b4048a86581e.
Report an issue: GitHub.