{"record":{"id":"351abce92def5ca9","repo":"n8n-io/n8n","slug":"circular-relations-detected-path-to-resolve-t","errorCode":null,"errorMessage":"Circular relations detected: ${path}. To resolve this issue you need to set nullable: true somewhere in this dependency structure.","messagePattern":"Circular relations detected: (.+?)\\. To resolve this issue you need to set nullable: true somewhere in this dependency structure\\.","errorType":"exception","errorClass":"CircularRelationsError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/metadata-builder/EntityMetadataValidator.ts","lineNumber":266,"sourceCode":"\t/**\n\t * Validates dependencies of the entity metadatas.\n\t */\n\tprotected validateDependencies(entityMetadatas: EntityMetadata[]) {\n\t\tconst graph = new DepGraph();\n\t\tentityMetadatas.forEach((entityMetadata) => {\n\t\t\tgraph.addNode(entityMetadata.name);\n\t\t});\n\t\tentityMetadatas.forEach((entityMetadata) => {\n\t\t\tentityMetadata.relationsWithJoinColumns\n\t\t\t\t.filter((relation) => !relation.isNullable)\n\t\t\t\t.forEach((relation) => {\n\t\t\t\t\tgraph.addDependency(entityMetadata.name, relation.inverseEntityMetadata.name);\n\t\t\t\t});\n\t\t});\n\t\ttry {\n\t\t\tgraph.overallOrder();\n\t\t} catch (err) {\n\t\t\tthrow new CircularRelationsError(\n\t\t\t\terr.toString().replace('Error: Dependency Cycle Found: ', ''),\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Validates eager relations to prevent circular dependency in them.\n\t */\n\tprotected validateEagerRelations(entityMetadatas: EntityMetadata[]) {\n\t\tentityMetadatas.forEach((entityMetadata) => {\n\t\t\tentityMetadata.eagerRelations.forEach((relation) => {\n\t\t\t\tif (relation.inverseRelation && relation.inverseRelation.isEager)\n\t\t\t\t\tthrow new TypeORMError(\n\t\t\t\t\t\t`Circular eager relations are disallowed. ` +\n\t\t\t\t\t\t\t`${entityMetadata.targetName}#${relation.propertyPath} contains \"eager: true\", and its inverse side ` +\n\t\t\t\t\t\t\t`${relation.inverseEntityMetadata.targetName}#${relation.inverseRelation.propertyPath} contains \"eager: true\" as well.` +\n\t\t\t\t\t\t\t` Remove \"eager: true\" from one side of the relation.`,\n\t\t\t\t\t);","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/metadata-builder/EntityMetadataValidator.ts#L248-L284","documentation":"TypeORM builds a dependency graph where each non-nullable join-column relation adds an edge from the entity to its inverse, then calls `graph.overallOrder()` to topologically sort entities for INSERT ordering. If the sort reports a dependency cycle, `CircularRelationsError` is thrown: two or more entities mutually require each other through NOT NULL foreign keys, so none can be inserted first.","triggerScenarios":"Entities A and B each carry a `@ManyToOne(() => Other, { nullable: false })` pointing at the other (or a longer cycle A->B->C->A) with all join columns non-nullable. Defining `@JoinColumn({ nullable: false })` on both sides of a mutual relation.","commonSituations":"Modeling a two-way mandatory ownership (user must have a profile, profile must have a user) where neither side is allowed null. Forgetting `nullable: true` on at least one side of a co-dependent pair.","solutions":["Set `nullable: true` on at least one join column in the cycle (the error message's own guidance) so TypeORM can insert, then update the FK in a second step.","Break the cycle in application code: insert parent without FK, then UPDATE the FK once the child exists.","Use a junction table (@ManyToMany) for the mutual dependency so neither side carries a mandatory FK."],"exampleFix":"// before — both sides NOT NULL → cycle\n@ManyToOne(() => B, { nullable: false }) b: B;\n@ManyToOne(() => A, { nullable: false }) a: A;\n\n// after — break the cycle\n@ManyToOne(() => B, { nullable: true }) b: B | null;","handlingStrategy":"validation","validationCode":"// Pre-flight: detect cycles among non-nullable join-column relations\nconst deps = new Map<string, string[]>();\nfor (const m of dataSource.entityMetadatas) deps.set(m.name, []);\nfor (const m of dataSource.entityMetadatas) {\n  for (const r of m.relationsWithJoinColumns) {\n    if (!r.isNullable) deps.get(m.name)!.push(r.inverseEntityMetadata.name);\n  }\n}\n// run a DFS cycle check on `deps` before calling initialize's schema build","typeGuard":null,"tryCatchPattern":"try { await dataSource.initialize(); } catch (e) { if (e instanceof CircularRelationsError) { console.error('Cycle path:', e.message); } throw e; }","preventionTips":["Make at least one join column in any mutual dependency `nullable: true`.","Insert co-dependent entities in two steps (parent first, then UPDATE the FK).","Use junction tables for truly mutual relationships."],"tags":["typeorm","relations","circular-dependency","schema-validation","foreign-keys"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}