typeorm/typeorm · 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

`MissingPrimaryColumnError` is thrown during metadata validation when a non-junction entity has zero `@PrimaryColumn`/`@PrimaryGeneratedColumn` columns. TypeORM requires a primary key for every entity to support updates, deletes, and relation joins.

Source

Thrown at src/metadata-builder/EntityMetadataValidator.ts:66

        this.validateDependencies(entityMetadatas)
        this.validateEagerRelations(entityMetadatas)
    }

    /**
     * Validates given entity metadata.
     *
     * @param entityMetadata
     * @param allEntityMetadatas
     * @param driver
     */
    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

View on GitHub (pinned to 04ff4daedc)

Solutions

  1. Add `@PrimaryGeneratedColumn()` (or `@PrimaryColumn`) to the entity
  2. If it is a junction table, model it as a many-to-many relation rather than a standalone entity

Example fix

// before
@Entity()
class User {
  @Column() id: number
}
// after
@Entity()
class User {
  @PrimaryGeneratedColumn() id: number
}
Defensive patterns

Strategy: validation

Validate before calling

function assertHasPrimaryKey(entity: Function) {
  const meta = dataSource.getMetadata(entity)
  if (!meta.primaryColumns.length && !meta.isJunction) {
    throw new Error(`${entity.name} has no primary column; add @PrimaryGeneratedColumn()`)
  }
}

Type guard

function hasPrimaryKey(metadata: EntityMetadata): boolean {
  return metadata.primaryColumns.length > 0 || metadata.isJunction
}

Prevention

When it happens

Trigger: Defining an entity class with only `@Column()` fields and no primary decorator; mapping a table or view without designating a key.

Common situations: Forgetting `@PrimaryGeneratedColumn()` when creating an entity; mapping a database view that has no natural key.

Related errors


AI-assisted analysis of typeorm/typeorm@04ff4daedc (2026-08-03). Data as JSON: /data/errors/51c58673f49020bf.json. Report an issue: GitHub.