{"id":"79f23af736fd9d7c","repo":"drizzle-team/drizzle-orm","slug":"table-sourcetable-table-symbol-name-not-foun","errorCode":null,"errorMessage":"Table \"${sourceTable[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":586,"sourceCode":"\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[] = [];\n\tfor (\n\t\tconst referencedTableRelation of Object.values(\n\t\t\treferencedTableConfig.relations,\n\t\t)\n\t) {\n\t\tif (\n\t\t\t(relation.relationName\n\t\t\t\t&& relation !== referencedTableRelation\n\t\t\t\t&& referencedTableRelation.relationName === relation.relationName)\n\t\t\t|| (!relation.relationName\n\t\t\t\t&& referencedTableRelation.referencedTable === relation.sourceTable)\n\t\t) {\n\t\t\treverseRelations.push(referencedTableRelation);","sourceCodeStart":568,"sourceCodeEnd":604,"githubUrl":"https://github.com/drizzle-team/drizzle-orm/blob/b7862528fd8fc39bc2653a6c18dad7c1f4e68d10/drizzle-orm/src/relations.ts#L568-L604","documentation":"normalizeRelation() throws when the relation's source table (the table on which relations() was called) is not present in tableNamesMap. This means the table owning the relation was not registered in the schema config, so its relation cannot be normalized.","triggerScenarios":"Calling relations(tableX, ...) and passing schema to drizzle() that does not include tableX. Defining relations in a separate file but forgetting to add the source table to the central schema export. Circular import leaving tableX undefined.","commonSituations":"Splitting relations into their own files and missing the source table in the aggregate schema. Refactoring that moves a table out of the schema index but leaves its relations file behind.","solutions":["Include every source table that has a relations() definition in the schema object passed to drizzle().","Consolidate schema into a single barrel export and pass it whole: import * as schema from './schema'; drizzle(client, { schema }).","Resolve circular imports so source tables are defined before their relations are evaluated."],"exampleFix":"// before (source table missing from schema)\nconst orderRelations = relations(orders, ({ one }) => ({\n  customer: one(customers, { fields: [orders.customerId], references: [customers.id] }),\n}));\nconst db = drizzle(client, { schema: { customers, orderRelations } }); // orders omitted\n\n// after\nconst db = drizzle(client, { schema: { customers, orders, orderRelations } });","handlingStrategy":"validation","validationCode":"// Validate that every table owning a relations() definition is in the schema.\nimport { Table } from 'drizzle-orm/table';\nimport { is } from 'drizzle-orm/entity';\nimport { Relations } from 'drizzle-orm/relations';\n\nfunction validateSourceTables(schema: Record<string, any>) {\n  const tableSet = new Set(Object.values(schema).filter((v) => is(v, Table)));\n  for (const v of Object.values(schema)) {\n    if (is(v, Relations)) {\n      const src = (v as any).table;\n      if (src && !tableSet.has(src)) {\n        throw new Error(`Source table \"${src[Table.Symbol.Name]}\" missing from schema`);\n      }\n    }\n  }\n}","typeGuard":"import { entityKind } from 'drizzle-orm/entity';\n\nfunction isRelations(v: unknown): boolean {\n  return (v as any)?.[entityKind] === 'Relations';\n}","tryCatchPattern":"try {\n  await db.query.posts.findFirst();\n} catch (e) {\n  if (e instanceof Error && /not found in schema/.test(e.message)) {\n    // add the missing source table to the schema export\n  } else throw e;\n}","preventionTips":["Always include source tables alongside their relations() in the schema barrel.","Pass the whole schema module: drizzle(client, { schema }).","Add a CI test that issues one relational query per table to catch missing registrations early."],"tags":["relations","schema","configuration","relational-queries"],"analyzedSha":"b7862528fd8fc39bc2653a6c18dad7c1f4e68d10","analyzedAt":"2026-08-03T18:11:14.318Z","schemaVersion":2}