{"id":"c61a2549558171a4","repo":"drizzle-team/drizzle-orm","slug":"table-relation-referencedtable-table-symbol-nam","errorCode":null,"errorMessage":"Table \"${relation.referencedTable[Table.Symbol.Name]}\" not found in schema","messagePattern":"Table \"(.+?)\" not found in schema","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"drizzle-orm/src/relations.ts","lineNumber":573,"sourceCode":"\tfields: AnyColumn[];\n\treferences: AnyColumn[];\n}\n\nexport function normalizeRelation(\n\tschema: TablesRelationalConfig,\n\ttableNamesMap: Record<string, string>,\n\trelation: Relation,\n): NormalizedRelation {\n\tif (is(relation, One) && relation.config) {\n\t\treturn {\n\t\t\tfields: relation.config.fields,\n\t\t\treferences: relation.config.references,\n\t\t};\n\t}\n\n\tconst referencedTableTsName = tableNamesMap[getTableUniqueName(relation.referencedTable)];\n\tif (!referencedTableTsName) {\n\t\tthrow new Error(\n\t\t\t`Table \"${relation.referencedTable[Table.Symbol.Name]}\" not found in schema`,\n\t\t);\n\t}\n\n\tconst referencedTableConfig = schema[referencedTableTsName];\n\tif (!referencedTableConfig) {\n\t\tthrow new Error(`Table \"${referencedTableTsName}\" not found in schema`);\n\t}\n\n\tconst sourceTable = relation.sourceTable;\n\tconst sourceTableTsName = tableNamesMap[getTableUniqueName(sourceTable)];\n\tif (!sourceTableTsName) {\n\t\tthrow new Error(\n\t\t\t`Table \"${sourceTable[Table.Symbol.Name]}\" not found in schema`,\n\t\t);\n\t}\n\n\tconst reverseRelations: Relation[] = [];","sourceCodeStart":555,"sourceCodeEnd":591,"githubUrl":"https://github.com/drizzle-team/drizzle-orm/blob/b7862528fd8fc39bc2653a6c18dad7c1f4e68d10/drizzle-orm/src/relations.ts#L555-L591","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before (tableB referenced but not in schema)\nexport const tableA = sqliteTable('a', { id: integer().primaryKey() });\nexport const tableB = sqliteTable('b', { aId: integer().references(() => tableA.id) });\nexport const tableARelations = relations(tableA, ({ many }) => ({\n  bs: many(tableBRelations),\n}));\nconst tableBRelations = relations(tableB, ({ one }) => ({\n  a: one(tableA, { fields: [tableB.aId], references: [tableA.id] }),\n}));\n// drizzle initialized with only { tableA, tableARelations } -> throws\n\n// after (include all tables + relations)\nconst db = drizzle(client, {\n  schema: { tableA, tableB, tableARelations, tableBRelations },\n});","handlingStrategy":"validation","validationCode":"// Validate the schema before passing to drizzle(): every relation's\n// referenced table must be present in the table set.\nimport { Table } from 'drizzle-orm/table';\nimport { is } from 'drizzle-orm/entity';\nimport { Relations } from 'drizzle-orm/relations';\n\nfunction validateReferencedTables(schema: Record<string, any>) {\n  const tables = new Set(Object.values(schema).filter((v) => is(v, Table)).map((t: any) => t[Table.Symbol.Name]));\n  for (const v of Object.values(schema)) {\n    if (is(v, Relations)) {\n      for (const r of Object.values((v as any).config)) {\n        const refName = r.referencedTable?.[Table.Symbol.Name];\n        if (refName && !tables.has(refName)) {\n          throw new Error(`Relation references table \"${refName}\" not present in schema`);\n        }\n      }\n    }\n  }\n}","typeGuard":"import { is, entityKind } from 'drizzle-orm/entity';\n\nfunction isTable(v: unknown): boolean {\n  return is(v, entityKind) && (v as any)?.[entityKind] === 'Table';\n}","tryCatchPattern":"try {\n  const db = drizzle(client, { schema });\n  await db.query.users.findMany();\n} catch (e) {\n  if (e instanceof Error && /not found in schema/.test(e.message)) {\n    // audit schema exports and add the missing referenced table\n  } else throw e;\n}","preventionTips":["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."],"tags":["relations","schema","configuration","relational-queries"],"analyzedSha":"b7862528fd8fc39bc2653a6c18dad7c1f4e68d10","analyzedAt":"2026-08-03T18:11:14.318Z","schemaVersion":2}