n8n-io/n8n · error · TypeORMError

Entities ${entityMetadata.name} and ${sameDiscriminatorValue

Error message

Entities ${entityMetadata.name} and ${sameDiscriminatorValueEntityMetadata.name} have the same discriminator values. Make sure they are different while using the @ChildEntity decorator.

What it means

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.

Source

Thrown at packages/@n8n/typeorm/src/metadata-builder/EntityMetadataValidator.ts:97

			if (typeof entityMetadata.discriminatorValue === 'undefined')
				throw new TypeORMError(
					`Entity ${entityMetadata.name} has an undefined discriminator value. Discriminator value should be defined.`,
				);

			const sameDiscriminatorValueEntityMetadata = allEntityMetadatas.find((metadata) => {
				return (
					metadata !== entityMetadata &&
					(metadata.inheritancePattern === 'STI' || metadata.tableType === 'entity-child') &&
					metadata.tableName === entityMetadata.tableName &&
					metadata.discriminatorValue === entityMetadata.discriminatorValue &&
					metadata.inheritanceTree.some(
						(parent) => entityMetadata.inheritanceTree.indexOf(parent) !== -1,
					)
				);
			});
			if (sameDiscriminatorValueEntityMetadata)
				throw new TypeORMError(
					`Entities ${entityMetadata.name} and ${sameDiscriminatorValueEntityMetadata.name} have the same discriminator values. Make sure they are different while using the @ChildEntity decorator.`,
				);
		}

		entityMetadata.relationCounts.forEach((relationCount) => {
			if (relationCount.relation.isManyToOne || relationCount.relation.isOneToOne)
				throw new TypeORMError(
					`Relation count can not be implemented on ManyToOne or OneToOne relations.`,
				);
		});

		entityMetadata.columns
			.filter((column) => !column.isVirtualProperty)
			.forEach((column) => {
				const normalizedColumn = driver.normalizeType(column) as ColumnType;
				if (driver.supportedDataTypes.indexOf(normalizedColumn) === -1)
					throw new DataTypeNotSupportedError(column, normalizedColumn, driver.options.type);
				if (column.length && driver.withLengthColumnTypes.indexOf(normalizedColumn) === -1)

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Give every sibling in the hierarchy a distinct @DiscriminatorValue.
  2. If two children were supposed to be one, consolidate them.
  3. Confirm tableName is intentional: if you meant separate tables, they are not actually in the same STI tree.

Example fix

// before
@ChildEntity() @DiscriminatorValue('doc')
export class Doc extends Content {}
@ChildEntity() @DiscriminatorValue('doc')
export class PdfDoc extends Content {}

// after
@ChildEntity() @DiscriminatorValue('doc')
export class Doc extends Content {}
@ChildEntity() @DiscriminatorValue('pdf')
export class PdfDoc extends Content {}
Defensive patterns

Strategy: validation

Validate before calling

function assertUniqueDiscriminatorValues(dataSource: DataSource): string[] {
  const byTable = new Map<string, Map<string, string[]>>();
  for (const meta of dataSource.entityMetadatas) {
    const isSti = meta.inheritancePattern === 'STI' || meta.tableType === 'entity-child';
    if (!isSti) continue;
    const inner = byTable.get(meta.tableName) ?? new Map();
    const key = String(meta.discriminatorValue);
    const list = inner.get(key) ?? [];
    list.push(meta.targetName);
    inner.set(key, list);
    byTable.set(meta.tableName, inner);
  }
  const problems: string[] = [];
  for (const [table, inner] of byTable) {
    for (const [value, names] of inner) {
      if (names.length > 1) problems.push(`${table}: discriminator '${value}' used by ${names.join(', ')}`);
    }
  }
  return problems;
}

Try / catch

try {
  await dataSource.initialize();
} catch (err) {
  if (err.message.includes('same discriminator values')) {
    // rename one of the colliding @DiscriminatorValue entries
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/71ae8e9266a184f7. Report an issue: GitHub.