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

  1. 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.
  2. 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.
  3. 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

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


AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03). Data as JSON: /data/errors/c61a2549558171a4.json. Report an issue: GitHub.