drizzle-team/drizzle-orm · error · Error
Table "${relation.referencedTable[Table.Symbol.Name]}" not f
Error message
Table "${relation.referencedTable[Table.Symbol.Name]}" not found in schema What it means
normalizeRelation() throws when a relation's referenced table (the target of a one()/many()) is not present in tableNamesMap, meaning it was never registered in the schema config passed to drizzle({schema}). Drizzle resolves relations by table unique name; a missing entry indicates the referenced table object was not exported/included in the schema map.
Source
Thrown at drizzle-orm/src/relations.ts:573
fields: AnyColumn[];
references: AnyColumn[];
}
export function normalizeRelation(
schema: TablesRelationalConfig,
tableNamesMap: Record<string, string>,
relation: Relation,
): NormalizedRelation {
if (is(relation, One) && relation.config) {
return {
fields: relation.config.fields,
references: relation.config.references,
};
}
const referencedTableTsName = tableNamesMap[getTableUniqueName(relation.referencedTable)];
if (!referencedTableTsName) {
throw new Error(
`Table "${relation.referencedTable[Table.Symbol.Name]}" not found in schema`,
);
}
const referencedTableConfig = schema[referencedTableTsName];
if (!referencedTableConfig) {
throw new Error(`Table "${referencedTableTsName}" not found in schema`);
}
const sourceTable = relation.sourceTable;
const sourceTableTsName = tableNamesMap[getTableUniqueName(sourceTable)];
if (!sourceTableTsName) {
throw new Error(
`Table "${sourceTable[Table.Symbol.Name]}" not found in schema`,
);
}
const reverseRelations: Relation[] = [];View on GitHub (pinned to b7862528fd)
Solutions
- Ensure every table referenced by any relation() is included in the schema object passed to drizzle(): export a single schema aggregating all tables and pass it as the second arg.
- Check for circular imports that cause a table to be undefined at the time extractTablesRelationalConfig runs; restructure imports so tables are defined before relations reference them.
- Verify each table is exported from exactly one module instance (avoid duplicate module resolution from path-alias or build-tool misconfiguration).
Example fix
// before (tableB referenced but not in schema)
export const tableA = sqliteTable('a', { id: integer().primaryKey() });
export const tableB = sqliteTable('b', { aId: integer().references(() => tableA.id) });
export const tableARelations = relations(tableA, ({ many }) => ({
bs: many(tableBRelations),
}));
const tableBRelations = relations(tableB, ({ one }) => ({
a: one(tableA, { fields: [tableB.aId], references: [tableA.id] }),
}));
// drizzle initialized with only { tableA, tableARelations } -> throws
// after (include all tables + relations)
const db = drizzle(client, {
schema: { tableA, tableB, tableARelations, tableBRelations },
}); Defensive patterns
Strategy: validation
Validate before calling
// Validate the schema before passing to drizzle(): every relation's
// referenced table must be present in the table set.
import { Table } from 'drizzle-orm/table';
import { is } from 'drizzle-orm/entity';
import { Relations } from 'drizzle-orm/relations';
function validateReferencedTables(schema: Record<string, any>) {
const tables = new Set(Object.values(schema).filter((v) => is(v, Table)).map((t: any) => t[Table.Symbol.Name]));
for (const v of Object.values(schema)) {
if (is(v, Relations)) {
for (const r of Object.values((v as any).config)) {
const refName = r.referencedTable?.[Table.Symbol.Name];
if (refName && !tables.has(refName)) {
throw new Error(`Relation references table "${refName}" not present in schema`);
}
}
}
}
} Type guard
import { is, entityKind } from 'drizzle-orm/entity';
function isTable(v: unknown): boolean {
return is(v, entityKind) && (v as any)?.[entityKind] === 'Table';
} Try / catch
try {
const db = drizzle(client, { schema });
await db.query.users.findMany();
} catch (e) {
if (e instanceof Error && /not found in schema/.test(e.message)) {
// audit schema exports and add the missing referenced table
} else throw e;
} Prevention
- Aggregate every table and relation into a single schema barrel and pass it whole to drizzle().
- Run a smoke relational query in tests/CI to surface missing-table errors at build time.
- Avoid circular imports between table and relation modules.
When it happens
Trigger: Defining relations({ tableA, ... }) where a relation points to tableB but tableB is omitted from the schema object passed to drizzle(). Circular imports that leave a table undefined at schema-build time. Forgetting to add a newly created table to the schema export.
Common situations: Schema files split across modules where one table is not re-exported from the central schema index. Refactoring that renames/moves a table but forgets to update the relations schema. TypeScript path aliases resolving to different module instances of the same table.
Related errors
- Table "${sourceTable[Table.Symbol.Name]}" not found in schem
- Table "${referencedTableTsName}" not found in schema
- There is not enough information to infer relation "${sourceT
- unsupported relation type
- Invalid relation "${relation.fieldName}" for table "${it.sch
AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03).
Data as JSON: /data/errors/c61a2549558171a4.json.
Report an issue: GitHub.