angular/angular-cli · error
Circular schematic reference detected: ${JSON.stringify(Arra
Error message
Circular schematic reference detected: ${JSON.stringify(Array.from(references))} What it means
NodeModuleEngineHost.resolve tracks the set of packages involved while resolving a schematic collection through node module resolution. If a package reappears as the requester (i.e. package A requires B which requires A, directly or transitively), resolve throws this Error with the full cycle of package names, preventing infinite recursion.
Source
Thrown at packages/angular_devkit/schematics/tools/node-module-engine-host.ts:41
constructor(name: string) {
super(`Package ${JSON.stringify(name)} was found but does not support schematics.`);
}
}
/**
* A simple EngineHost that uses NodeModules to resolve collections.
*/
export class NodeModulesEngineHost extends FileSystemEngineHostBase {
constructor(private readonly paths?: string[]) {
super();
}
private resolve(name: string, requester?: string, references = new Set<string>()): string {
// Keep track of the package requesting the schematic, in order to avoid infinite recursion
if (requester) {
if (references.has(requester)) {
references.add(requester);
throw new Error(
'Circular schematic reference detected: ' + JSON.stringify(Array.from(references)),
);
} else {
references.add(requester);
}
}
let collectionPath: string | undefined = undefined;
const resolveOptions = {
paths: requester ? [dirname(requester), ...(this.paths || [])] : this.paths,
};
// Try to resolve as a package
try {
const packageJsonPath = require.resolve(`${name}/package.json`, resolveOptions);
const { schematics } = require(packageJsonPath);
if (!schematics || typeof schematics !== 'string') {View on GitHub (pinned to bb72145f9a)
Solutions
- Inspect the package list in the error to identify the cycle (e.g. ["@a/pkg", "@b/pkg"]).
- Break the cycle: make one package's collection not `extends` or reference the other (inline the shared schematics or extract a third base package).
- Check the offending package.json/collection.json `extends`/dependency fields and remove the self- or circular reference.
- Rebuild and reinstall the affected local packages, then retry.
Example fix
// before (pkg-b collection.json)
{ "extends": ["@a/pkg"], "schematics": { ... } } // while @a/pkg collection.json extends @b/pkg
// after (break the cycle)
{ "schematics": { ... } } // remove the extends entry from one of the two packages Defensive patterns
Strategy: try-catch
Validate before calling
// Detect extends cycles before loading (graph check over collection.json extends fields)
function detectCycle(graph: Record<string, string[]>, start: string) {
const seen = new Set<string>();
const dfs = (n: string): boolean => {
if (n === start && seen.size) return true;
if (seen.has(n)) return true;
seen.add(n);
return (graph[n] || []).some(dfs);
};
if (dfs(start)) throw new Error(`Circular collection extends involving ${start}`);
} Try / catch
try {
const collection = engine.createCollection(name);
} catch (e) {
if (String(e.message).includes('Circular schematic reference detected')) {
console.error(e.message); // lists the cycle; break it in the listed package's collection.json
process.exitCode = 1;
} else throw e;
} Prevention
- Never let two collections `extends` each other; extract shared schematics into a base package.
- Never set a package's collection `extends` (or dependency) to itself.
- Run a dependency-cycle check (e.g. madge) over collection extends graphs in CI.
When it happens
Trigger: Resolving a collection whose package.json (or an intermediate dependency's) points back to a package already in the `references` set — e.g. package A's schematic extends/references collection of B, and B references A; `references.has(requester)` becomes true.
Common situations: Two schematic packages that `extends` each other's collections; a package declaring itself as its own dependency or extending its own collection; accidentally publishing a collection.json whose `extends` points at the same package name; circular npm dependencies introduced by a refactor.
Related errors
- Unknown schematics built-in module '${id}' requested from sc
- Schematic ${JSON.stringify(name)} cannot resolve the factory
- Collection ${JSON.stringify(name)} cannot be resolved.
- Collection ${JSON.stringify(name)} cannot be resolved.
- schematicName cannot be undefined.
AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30).
Data as JSON: /api/errors/4673eb6ec12a9739.
Report an issue: GitHub.