typeorm/typeorm · error · UpdateValuesMissingError
Cannot perform update query because update values are not de
Error message
Cannot perform update query because update values are not defined. Call "qb.set(...)" method to specify updated values.
What it means
Thrown (as UpdateValuesMissingError) at the end of UpdateQueryBuilder.createUpdateExpression() when updateColumnAndValues is empty after processing the SET object. This happens when every key in the SET was filtered out: either all columns are marked isUpdate:false, or (with entity metadata) the normalized values set had no updatable columns left.
Source
Thrown at src/query-builder/UpdateQueryBuilder.ts:731
this.dataSource.driver.options.type === "spanner") &&
value === null
) {
updateColumnAndValues.push(this.escape(key) + " = NULL")
} else {
// we need to store array values in a special class to make sure parameter replacement will work correctly
// if (value instanceof Array)
// value = new ArrayParameter(value);
const paramName = this.createParameter(value)
updateColumnAndValues.push(
this.escape(key) + " = " + paramName,
)
}
})
}
if (updateColumnAndValues.length <= 0) {
throw new UpdateValuesMissingError()
}
// get a table name and all column database names
const whereExpression = this.createWhereExpression()
const returningExpression = this.createReturningExpression("update")
if (returningExpression === "") {
return `UPDATE ${this.getTableName(
this.getMainTableName(),
)} SET ${updateColumnAndValues.join(", ")}${whereExpression}` // todo: how do we replace aliases in where to nothing?
}
if (this.dataSource.driver.options.type === "mssql") {
return `UPDATE ${this.getTableName(
this.getMainTableName(),
)} SET ${updateColumnAndValues.join(
", ",
)} OUTPUT ${returningExpression}${whereExpression}`
}View on GitHub (pinned to 04ff4daedc)
Solutions
- Ensure at least one column in your .set(...) is updatable (@Column({ update: true }) or default).
- If a column must be immutable, update a different column or remove update:false.
- Before executing, confirm Object.keys(setObject).length > 0 and that at least one maps to an updatable column.
- For dynamic patches, short-circuit (no-op) when the resolved updatable-column set is empty.
Example fix
// before — only non-updatable columns
@Entity()
class Post { @Column({ update: false }) createdAt: Date; }
await repo.update({ id }, { createdAt: new Date() }); // -> UpdateValuesMissingError
// after — include an updatable column, or skip the call
const patch = { title: 'new' };
if (Object.keys(patch).length) await repo.update({ id }, patch); Defensive patterns
Strategy: validation
Validate before calling
const updatable = new Set(
repo.metadata.columns.filter((c) => c.isUpdate).map((c) => c.propertyPath),
);
const hasUpdatable = Object.keys(patch).some((k) => updatable.has(k));
if (!hasUpdatable) throw new Error('Patch contains no updatable columns');
await repo.update({ id }, patch); Type guard
function hasUpdatableColumn(metadata: import('typeorm').EntityMetadata, patch: object): boolean {
const updatable = new Set(metadata.columns.filter((c) => c.isUpdate).map((c) => c.propertyPath));
return Object.keys(patch).some((k) => updatable.has(k));
} Prevention
- Ensure at least one column in set() is updatable (update: true).
- Short-circuit (no-op) when a dynamic patch resolves to no updatable columns.
- Review @Column({ update: false }) annotations before relying on a column in updates.
When it happens
Trigger: Calling update().set({...}).execute() where every column in the set is @Column({ update: false }) (e.g. createdAt), so the loop skips them all and the final length check trips. Also possible when the set object is empty after stripping undefined values.
Common situations: Trying to update a create-only/immutable column; passing an object whose only keys are non-updatable columns; dynamically building a patch that ends up empty; migrating a column to update:false without updating callers.
Related errors
- Provided entity does not have ids set, cannot perform operat
- Property "${propertyPath}" was not found in "${metadata.targ
- Check expression is required
- Exclusion expression is required
- Primary column ${(<any>object.constructor).name}#${propertyN
AI-assisted analysis of typeorm/typeorm@04ff4daedc (2026-08-03).
Data as JSON: /data/errors/3d14091ed810a546.json.
Report an issue: GitHub.