typeorm/typeorm · error · TypeORMError
Unique constraint ${indexName}contains column that is missin
Error message
Unique constraint ${indexName}contains column that is missing in the entity (${entityName}): ${propertyName} What it means
The unique-constraint analogue of the index column-missing error. Thrown during `UniqueMetadata.build()` when a column listed in `@Unique(["..."])` is neither a real column nor an owning relation with a join column on this entity. Same resolution logic as IndexMetadata: walk columns then `isWithJoinColumn` relations, abort if nothing matches.
Source
Thrown at src/metadata/UniqueMetadata.ts:163
(column) => column.propertyPath === propertyName,
)
if (columnWithSameName) {
return [columnWithSameName]
}
const relationWithSameName =
this.entityMetadata.relations.find(
(relation) =>
relation.isWithJoinColumn &&
relation.propertyName === propertyName,
)
if (relationWithSameName) {
return relationWithSameName.joinColumns
}
const indexName = this.givenName
? '"' + this.givenName + '" '
: ""
const entityName = this.entityMetadata.targetName
throw new TypeORMError(
`Unique constraint ${indexName}contains column that is missing in the entity (${entityName}): ` +
propertyName,
)
})
.reduce((a, b) => a.concat(b))
}
this.columnNamesWithOrderingMap = Object.keys(map).reduce(
(updatedMap, key) => {
const column = this.entityMetadata.columns.find(
(column) => column.propertyPath === key,
)
if (column) updatedMap[column.databasePath] = map[key]
return updatedMap
},
{} as { [key: string]: number },
)View on GitHub (pinned to 04ff4daedc)
Solutions
- Verify each name in the @Unique array maps to a @Column or an owning relation (@ManyToOne / @OneToOne owner) on this entity.
- For embeddable columns, use the full property path (e.g. `"address.zip"`) or place the @Unique inside the embeddable class.
- Re-check after renames — search the codebase for the old column name in @Unique decorators.
Example fix
// before
@Entity()
@Unique("uq_email", ["emial"]) // typo
export class User { @Column() email: string }
// after
@Entity()
@Unique("uq_email", ["email"])
export class User { @Column() email: string } Defensive patterns
Strategy: validation
Validate before calling
// Mirror of the @Index validation, applied to @Unique column lists
function validateUniqueColumns(
entityColumns: string[],
owningRelations: string[],
uniqueColumns: string[],
): string[] {
const valid = new Set([...entityColumns, ...owningRelations])
return uniqueColumns.filter((c) => !valid.has(c))
} Type guard
function isColumnOrOwningRelation(meta: any, prop: string): boolean {
if (meta.columns.some((c: any) => c.propertyPath === prop)) return true
const r = meta.relations.find((rel: any) => rel.propertyName === prop)
return !!r && r.isWithJoinColumn
} Prevention
- Keep @Unique column lists in sync with renames (grep the old name).
- For embeddables, use the full property path or move the @Unique into the embeddable.
- Initialize the DataSource in CI tests to catch schema-build errors.
When it happens
Trigger: `@Unique("uq_x", ["misspelled"])`; `@Unique(["items"])` where `items` is a @OneToMany (no join column on this entity); referencing a column that was removed; using a property name from an embeddable without the embed prefix.
Common situations: Renaming a column without updating @Unique; misunderstanding that unique constraints on relations must reference the owning side; copy-paste between entities; embeddable path mistakes.
Related errors
- Index ${indexName}contains column that is missing in the ent
- Cannot find relation ${propertyPath}. Wrong relation specifi
- Unsupported index type
- No metadata for "${target}" was found.
- Relation "${relationPropertyPath}" was not found in ${entity
AI-assisted analysis of typeorm/typeorm@04ff4daedc (2026-08-03).
Data as JSON: /data/errors/ef026467da41d07c.json.
Report an issue: GitHub.