n8n-io/n8n · critical · MissingPrimaryColumnError

Entity "${entityMetadata.name}" does not have a primary colu

Error message

Entity "${entityMetadata.name}" does not have a primary column. Primary column is required to have in all your entities. Use @PrimaryColumn decorator to add a primary column to your entity.

What it means

Thrown by EntityMetadataValidator.validate via MissingPrimaryColumnError when an entity has zero primary columns and is not a junction (isJunction) table. The guard is `if (!entityMetadata.primaryColumns.length && !entityMetadata.isJunction)`. Every persistable entity must declare a primary key.

Source

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

	/**
	 * Validates all given entity metadatas.
	 */
	validateMany(entityMetadatas: EntityMetadata[], driver: Driver) {
		entityMetadatas.forEach((entityMetadata) =>
			this.validate(entityMetadata, entityMetadatas, driver),
		);
		this.validateDependencies(entityMetadatas);
		this.validateEagerRelations(entityMetadatas);
	}

	/**
	 * Validates given entity metadata.
	 */
	validate(entityMetadata: EntityMetadata, allEntityMetadatas: EntityMetadata[], driver: Driver) {
		// check if table metadata has an id
		if (!entityMetadata.primaryColumns.length && !entityMetadata.isJunction)
			throw new MissingPrimaryColumnError(entityMetadata);

		// if entity has multiple primary keys and uses custom constraint name,
		// then all primary keys should have the same constraint name
		if (entityMetadata.primaryColumns.length > 1) {
			const areConstraintNamesEqual = entityMetadata.primaryColumns.every(
				(columnMetadata, i, columnMetadatas) =>
					columnMetadata.primaryKeyConstraintName === columnMetadatas[0].primaryKeyConstraintName,
			);
			if (!areConstraintNamesEqual) {
				throw new TypeORMError(
					`Entity ${entityMetadata.name} has multiple primary columns with different constraint names. Constraint names should be the equal.`,
				);
			}
		}

		// validate if table is using inheritance it has a discriminator
		// also validate if discriminator values are not empty and not repeated
		if (

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Add @PrimaryGeneratedColumn() (auto-increment) or @PrimaryColumn() (user-supplied) to one property.
  2. For composite keys, use multiple @PrimaryColumn decorators on each constituent field.
  3. If the class is intentionally a pure view, mark it with @ViewEntity so it is excluded from the PK requirement path.

Example fix

// before
@Entity()
export class AuditLog {
  @Column() action: string;
}

// after
@Entity()
export class AuditLog {
  @PrimaryGeneratedColumn() id: number;
  @Column() action: string;
}
Defensive patterns

Strategy: validation

Validate before calling

function assertAllEntitiesHavePk(dataSource: DataSource): void {
  const missing = dataSource.entityMetadatas
    .filter((m) => !m.isJunction && m.primaryColumns.length === 0)
    .map((m) => m.targetName);
  if (missing.length) {
    throw new Error('Entities without a primary column: ' + missing.join(', '));
  }
}

Try / catch

try {
  await dataSource.initialize();
} catch (err) {
  if (err.message.includes('does not have a primary column')) {
    // surface the entity name; add @PrimaryGeneratedColumn
  }
  throw err;
}

Prevention

When it happens

Trigger: Defining an @Entity class with no @PrimaryColumn, @PrimaryGeneratedColumn, or @ObjectIdColumn; only view entities (which set isJunction/other flags) are exempt, but plain entities are not.

Common situations: New entity authored without a PK decorator; renaming @PrimaryGeneratedColumn to a plain @Column during refactor; migrating from MongoDB ObjectId columns and forgetting the decorator.

Related errors


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