{"record":{"id":"71ae8e9266a184f7","repo":"n8n-io/n8n","slug":"entities-entitymetadata-name-and-samediscrimi","errorCode":null,"errorMessage":"Entities ${entityMetadata.name} and ${sameDiscriminatorValueEntityMetadata.name} have the same discriminator values. Make sure they are different while using the @ChildEntity decorator.","messagePattern":"Entities (.+?) and (.+?) have the same discriminator values\\. Make sure they are different while using the @ChildEntity decorator\\.","errorType":"exception","errorClass":"TypeORMError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/metadata-builder/EntityMetadataValidator.ts","lineNumber":97,"sourceCode":"\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);\n\t\t\t});\n\t\t\tif (sameDiscriminatorValueEntityMetadata)\n\t\t\t\tthrow new TypeORMError(\n\t\t\t\t\t`Entities ${entityMetadata.name} and ${sameDiscriminatorValueEntityMetadata.name} have the same discriminator values. Make sure they are different while using the @ChildEntity decorator.`,\n\t\t\t\t);\n\t\t}\n\n\t\tentityMetadata.relationCounts.forEach((relationCount) => {\n\t\t\tif (relationCount.relation.isManyToOne || relationCount.relation.isOneToOne)\n\t\t\t\tthrow new TypeORMError(\n\t\t\t\t\t`Relation count can not be implemented on ManyToOne or OneToOne relations.`,\n\t\t\t\t);\n\t\t});\n\n\t\tentityMetadata.columns\n\t\t\t.filter((column) => !column.isVirtualProperty)\n\t\t\t.forEach((column) => {\n\t\t\t\tconst normalizedColumn = driver.normalizeType(column) as ColumnType;\n\t\t\t\tif (driver.supportedDataTypes.indexOf(normalizedColumn) === -1)\n\t\t\t\t\tthrow new DataTypeNotSupportedError(column, normalizedColumn, driver.options.type);\n\t\t\t\tif (column.length && driver.withLengthColumnTypes.indexOf(normalizedColumn) === -1)","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/metadata-builder/EntityMetadataValidator.ts#L79-L115","documentation":"Thrown by EntityMetadataValidator.validate when two entities in the same STI tree share the same discriminatorValue AND the same tableName. The validator scans allEntityMetadatas for another metadata with matching discriminator value, matching tableName, STI/child table type, and an overlapping inheritanceTree; on match it throws naming both entities.","triggerScenarios":"Two @ChildEntity classes in the same hierarchy with the same @DiscriminatorValue string, or two children that both fall back to the same class-name-derived default.","commonSituations":"Copy-pasting a child entity and forgetting to change the discriminator value; rename of a class without updating its explicit discriminator; merging two STI trees under one table.","solutions":["Give every sibling in the hierarchy a distinct @DiscriminatorValue.","If two children were supposed to be one, consolidate them.","Confirm tableName is intentional: if you meant separate tables, they are not actually in the same STI tree."],"exampleFix":"// before\n@ChildEntity() @DiscriminatorValue('doc')\nexport class Doc extends Content {}\n@ChildEntity() @DiscriminatorValue('doc')\nexport class PdfDoc extends Content {}\n\n// after\n@ChildEntity() @DiscriminatorValue('doc')\nexport class Doc extends Content {}\n@ChildEntity() @DiscriminatorValue('pdf')\nexport class PdfDoc extends Content {}","handlingStrategy":"validation","validationCode":"function assertUniqueDiscriminatorValues(dataSource: DataSource): string[] {\n  const byTable = new Map<string, Map<string, string[]>>();\n  for (const meta of dataSource.entityMetadatas) {\n    const isSti = meta.inheritancePattern === 'STI' || meta.tableType === 'entity-child';\n    if (!isSti) continue;\n    const inner = byTable.get(meta.tableName) ?? new Map();\n    const key = String(meta.discriminatorValue);\n    const list = inner.get(key) ?? [];\n    list.push(meta.targetName);\n    inner.set(key, list);\n    byTable.set(meta.tableName, inner);\n  }\n  const problems: string[] = [];\n  for (const [table, inner] of byTable) {\n    for (const [value, names] of inner) {\n      if (names.length > 1) problems.push(`${table}: discriminator '${value}' used by ${names.join(', ')}`);\n    }\n  }\n  return problems;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await dataSource.initialize();\n} catch (err) {\n  if (err.message.includes('same discriminator values')) {\n    // rename one of the colliding @DiscriminatorValue entries\n  }\n  throw err;\n}","preventionTips":["Maintain an explicit table of discriminator values per STI hierarchy so collisions are visible.","Add the post-init uniqueness validator above to CI.","On renaming a child entity, audit its discriminator value for accidental duplication."],"tags":["single-table-inheritance","discriminator","child-entity","startup"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}