drizzle-team/drizzle-orm · error · Error
Table '${tableGen.tableName}' does not have primary or (uniq
Error message
Table '${tableGen.tableName}' does not have primary or (unique and notNull) column. Can't seed table with cyclic relation. What it means
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.
Source
Thrown at drizzle-seed/src/services/SeedService.ts:1124
};
filterCyclicTables = (tablesGenerators: ReturnType<typeof this.generatePossibleGenerators>) => {
const filteredTablesGenerators = tablesGenerators.filter((tableGen) =>
tableGen.columnsPossibleGenerators.some((columnGen) =>
columnGen.isCyclic === true && columnGen.wasDefinedBefore === true
)
);
const tablesUniqueNotNullColumn: { [tableName: string]: { uniqueNotNullColName: string } } = {};
for (const [idx, tableGen] of filteredTablesGenerators.entries()) {
const uniqueNotNullColName = filteredTablesGenerators[idx]!.columnsPossibleGenerators.find((colGen) =>
colGen.primary === true
|| (colGen.isUnique === true
&& colGen.notNull === true)
)?.columnName;
if (uniqueNotNullColName === undefined) {
throw new Error(
`Table '${tableGen.tableName}' does not have primary or (unique and notNull) column. Can't seed table with cyclic relation.`,
);
}
tablesUniqueNotNullColumn[tableGen.tableName] = { uniqueNotNullColName };
filteredTablesGenerators[idx]!.columnsPossibleGenerators = tableGen.columnsPossibleGenerators.filter((colGen) =>
(colGen.isCyclic === true && colGen.wasDefinedBefore === true) || colGen.columnName === uniqueNotNullColName
).map((colGen) => {
const newColGen = { ...colGen };
newColGen.wasDefinedBefore = false;
return newColGen;
});
}
return { filteredTablesGenerators, tablesUniqueNotNullColumn };
};
generateTablesValues = async (View on GitHub (pinned to b7862528fd)
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.
Example fix
// before — junction table, no PK, part of cycle
export const links = pgTable('links', {
aId: integer().references(() => a.id),
bId: integer().references(() => b.id),
});
// after — add a primary key
export const links = pgTable('links', {
id: serial('id').primaryKey(),
aId: integer().references(() => a.id),
bId: integer().references(() => b.id),
}); Defensive patterns
Strategy: validation
Validate before calling
// Verify every table in a cyclic relation has a PK or (unique && notNull) column.
function cyclicTablesHaveKey(
tables: Array<{ name: string; columns: Array<{ name: string; primary: boolean; isUnique: boolean; notNull: boolean }> }>,
cyclicTableNames: Set<string>
): string[] {
const missing: string[] = [];
for (const t of tables) {
if (!cyclicTableNames.has(t.name)) continue;
const hasKey = t.columns.some((c) => c.primary || (c.isUnique && c.notNull));
if (!hasKey) missing.push(t.name);
}
return missing;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- The '${table1.name}' and '${table2.name}' tables have not nu
- unsupported dialect
- unsupported relation type
- Invalid relation "${relation.fieldName}" for table "${it.sch
- Table "${relation.referencedTable[Table.Symbol.Name]}" not f
AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03).
Data as JSON: /data/errors/51b60ab92ad6888a.json.
Report an issue: GitHub.