{"id":"51b60ab92ad6888a","repo":"drizzle-team/drizzle-orm","slug":"table-tablegen-tablename-does-not-have-primar","errorCode":null,"errorMessage":"Table '${tableGen.tableName}' does not have primary or (unique and notNull) column. Can't seed table with cyclic relation.","messagePattern":"Table '(.+?)' does not have primary or \\(unique and notNull\\) column\\. Can't seed table with cyclic relation\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"drizzle-seed/src/services/SeedService.ts","lineNumber":1124,"sourceCode":"\t};\n\n\tfilterCyclicTables = (tablesGenerators: ReturnType<typeof this.generatePossibleGenerators>) => {\n\t\tconst filteredTablesGenerators = tablesGenerators.filter((tableGen) =>\n\t\t\ttableGen.columnsPossibleGenerators.some((columnGen) =>\n\t\t\t\tcolumnGen.isCyclic === true && columnGen.wasDefinedBefore === true\n\t\t\t)\n\t\t);\n\n\t\tconst tablesUniqueNotNullColumn: { [tableName: string]: { uniqueNotNullColName: string } } = {};\n\n\t\tfor (const [idx, tableGen] of filteredTablesGenerators.entries()) {\n\t\t\tconst uniqueNotNullColName = filteredTablesGenerators[idx]!.columnsPossibleGenerators.find((colGen) =>\n\t\t\t\tcolGen.primary === true\n\t\t\t\t|| (colGen.isUnique === true\n\t\t\t\t\t&& colGen.notNull === true)\n\t\t\t)?.columnName;\n\t\t\tif (uniqueNotNullColName === undefined) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Table '${tableGen.tableName}' does not have primary or (unique and notNull) column. Can't seed table with cyclic relation.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\ttablesUniqueNotNullColumn[tableGen.tableName] = { uniqueNotNullColName };\n\n\t\t\tfilteredTablesGenerators[idx]!.columnsPossibleGenerators = tableGen.columnsPossibleGenerators.filter((colGen) =>\n\t\t\t\t(colGen.isCyclic === true && colGen.wasDefinedBefore === true) || colGen.columnName === uniqueNotNullColName\n\t\t\t).map((colGen) => {\n\t\t\t\tconst newColGen = { ...colGen };\n\t\t\t\tnewColGen.wasDefinedBefore = false;\n\t\t\t\treturn newColGen;\n\t\t\t});\n\t\t}\n\n\t\treturn { filteredTablesGenerators, tablesUniqueNotNullColumn };\n\t};\n\n\tgenerateTablesValues = async (","sourceCodeStart":1106,"sourceCodeEnd":1142,"githubUrl":"https://github.com/drizzle-team/drizzle-orm/blob/b7862528fd8fc39bc2653a6c18dad7c1f4e68d10/drizzle-seed/src/services/SeedService.ts#L1106-L1142","documentation":"To seed cyclic tables, drizzle-seed must defer one side of the cycle and later update it. It needs a column to use as a stable identity key for that update — either a primary key, or a column that is both unique AND notNull. If a table in a cyclic relation has neither, filterCyclicTables throws because there is no reliable column to match deferred rows.","triggerScenarios":"A table participating in a cyclic FK relationship that has no primary key and no unique+notNull column; common in pure junction/link tables with only two nullable FK columns.","commonSituations":"Junction tables in many-to-many relationships that participate in a cycle; tables where the PK was accidentally removed or made non-unique during a migration.","solutions":["Add a primary key column (e.g. an auto-incrementing id) to the table.","Add a unique + notNull constraint to an existing column that can serve as the identity key.","If the table is a pure junction, break the cycle by making one FK nullable so the table is no longer treated as cyclic."],"exampleFix":"// before — junction table, no PK, part of cycle\nexport const links = pgTable('links', {\n  aId: integer().references(() => a.id),\n  bId: integer().references(() => b.id),\n});\n// after — add a primary key\nexport const links = pgTable('links', {\n  id: serial('id').primaryKey(),\n  aId: integer().references(() => a.id),\n  bId: integer().references(() => b.id),\n});","handlingStrategy":"validation","validationCode":"// Verify every table in a cyclic relation has a PK or (unique && notNull) column.\nfunction cyclicTablesHaveKey(\n  tables: Array<{ name: string; columns: Array<{ name: string; primary: boolean; isUnique: boolean; notNull: boolean }> }>,\n  cyclicTableNames: Set<string>\n): string[] {\n  const missing: string[] = [];\n  for (const t of tables) {\n    if (!cyclicTableNames.has(t.name)) continue;\n    const hasKey = t.columns.some((c) => c.primary || (c.isUnique && c.notNull));\n    if (!hasKey) missing.push(t.name);\n  }\n  return missing;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always define a primary key on tables that participate in cyclic relationships.","For junction tables in cycles, add a serial PK or a unique+notNull column.","Review cyclic table design for seeding during schema planning."],"tags":["cyclic","primary-key","unique","junction-table","relations"],"analyzedSha":"b7862528fd8fc39bc2653a6c18dad7c1f4e68d10","analyzedAt":"2026-08-03T18:11:14.318Z","schemaVersion":2}