{"record":{"id":"2bac1cf20c3a246b","repo":"n8n-io/n8n","slug":"entity-entitymetadata-name-using-single-table-i","errorCode":null,"errorMessage":"Entity ${entityMetadata.name} using single-table inheritance, it should also have a discriminator column. Did you forget to put discriminator column options?","messagePattern":"Entity (.+?) using single-table inheritance, it should also have a discriminator column\\. Did you forget to put discriminator column options\\?","errorType":"exception","errorClass":"TypeORMError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/metadata-builder/EntityMetadataValidator.ts","lineNumber":76,"sourceCode":"\t\t\tconst areConstraintNamesEqual = entityMetadata.primaryColumns.every(\n\t\t\t\t(columnMetadata, i, columnMetadatas) =>\n\t\t\t\t\tcolumnMetadata.primaryKeyConstraintName === columnMetadatas[0].primaryKeyConstraintName,\n\t\t\t);\n\t\t\tif (!areConstraintNamesEqual) {\n\t\t\t\tthrow new TypeORMError(\n\t\t\t\t\t`Entity ${entityMetadata.name} has multiple primary columns with different constraint names. Constraint names should be the equal.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// validate if table is using inheritance it has a discriminator\n\t\t// also validate if discriminator values are not empty and not repeated\n\t\tif (\n\t\t\tentityMetadata.inheritancePattern === 'STI' ||\n\t\t\tentityMetadata.tableType === 'entity-child'\n\t\t) {\n\t\t\tif (!entityMetadata.discriminatorColumn)\n\t\t\t\tthrow new TypeORMError(\n\t\t\t\t\t`Entity ${entityMetadata.name} using single-table inheritance, it should also have a discriminator column. Did you forget to put discriminator column options?`,\n\t\t\t\t);\n\n\t\t\tif (typeof entityMetadata.discriminatorValue === 'undefined')\n\t\t\t\tthrow new TypeORMError(\n\t\t\t\t\t`Entity ${entityMetadata.name} has an undefined discriminator value. Discriminator value should be defined.`,\n\t\t\t\t);\n\n\t\t\tconst sameDiscriminatorValueEntityMetadata = allEntityMetadatas.find((metadata) => {\n\t\t\t\treturn (\n\t\t\t\t\tmetadata !== entityMetadata &&\n\t\t\t\t\t(metadata.inheritancePattern === 'STI' || metadata.tableType === 'entity-child') &&\n\t\t\t\t\tmetadata.tableName === entityMetadata.tableName &&\n\t\t\t\t\tmetadata.discriminatorValue === entityMetadata.discriminatorValue &&\n\t\t\t\t\tmetadata.inheritanceTree.some(\n\t\t\t\t\t\t(parent) => entityMetadata.inheritanceTree.indexOf(parent) !== -1,\n\t\t\t\t\t)\n\t\t\t\t);","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/metadata-builder/EntityMetadataValidator.ts#L58-L94","documentation":"Thrown by EntityMetadataValidator.validate inside the single-table-inheritance branch (inheritancePattern === 'STI' or tableType === 'entity-child') when no discriminatorColumn exists on the metadata. STI requires a discriminator column on the root entity so TypeORM can store the concrete subclass per row.","triggerScenarios":"Using @SingleEntityInheritance / extending an @Entity class (or marking @ChildEntity) without declaring @DiscriminatorColumn on the root entity, or declaring it on the child instead of the root.","commonSituations":"Adding a child entity to an STI hierarchy whose parent lacks a discriminator; refactoring an entity into STI and forgetting the discriminator decorator.","solutions":["Add @DiscriminatorColumn({ name: 'type', type: 'string' }) to the root abstract/base entity of the hierarchy.","Confirm inheritancePattern resolves to STI (TypeORM infers it from extend patterns); if you did not intend STI, remove the @ChildEntity decorator or the extends chain.","Re-run schema sync after the change so the discriminator column is materialized in the DB."],"exampleFix":"// before\n@Entity()\nexport abstract class Content {\n  @PrimaryGeneratedColumn() id: number;\n}\n@Entity()\nexport class Article extends Content {}\n\n// after\n@Entity()\n@DiscriminatorColumn({ name: 'kind', type: 'string' })\nexport abstract class Content {\n  @PrimaryGeneratedColumn() id: number;\n}\n@ChildEntity()\nexport class Article extends Content {}","handlingStrategy":"validation","validationCode":"function assertStiHasDiscriminator(dataSource: DataSource): string[] {\n  const problems: string[] = [];\n  for (const meta of dataSource.entityMetadatas) {\n    const isSti = meta.inheritancePattern === 'STI' || meta.tableType === 'entity-child';\n    if (isSti && !meta.discriminatorColumn) {\n      problems.push(`${meta.targetName} uses STI but has no discriminator column`);\n    }\n  }\n  return problems;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await dataSource.initialize();\n} catch (err) {\n  if (err.message.includes('single-table inheritance') && err.message.includes('discriminator column')) {\n    // add @DiscriminatorColumn on the root entity\n  }\n  throw err;\n}","preventionTips":["Treat STI hierarchies as a single unit: root must carry @DiscriminatorColumn before any @ChildEntity is added.","Add an integration test that boots the DataSource for every STI tree in the app.","Document the STI root prominently so contributors do not add children to a non-STI base."],"tags":["single-table-inheritance","discriminator","metadata","startup"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}