n8n-io/n8n · error · TypeORMError
You cannot update relations of multiple entities with the sa
Error message
You cannot update relations of multiple entities with the same related object. Provide a single entity into .of method.
What it means
In RelationUpdater.update for isOneToOneNotOwner || isOneToMany branches, TypeORM throws TypeORMError if this.expressionMap.of is an array. The inverse-side update strategy writes the parent's FK value into the related rows; applying the same value to multiple parents is ambiguous, so a single parent is required.
Source
Thrown at packages/@n8n/typeorm/src/query-builder/RelationUpdater.ts:87
parameters[parameterName] = ObjectUtils.isObject(of)
? column.referencedColumn!.getEntityValue(of)
: of;
conditions.push(`${column.propertyPath} = :${parameterName}`);
});
});
const condition = conditions.map((str) => '(' + str + ')').join(' OR ');
if (!condition) return;
await this.queryBuilder
.createQueryBuilder()
.update(relation.inverseEntityMetadata.target)
.set(updateSet)
.where(condition)
.setParameters(parameters)
.execute();
} else if (relation.isOneToOneNotOwner || relation.isOneToMany) {
if (Array.isArray(this.expressionMap.of))
throw new TypeORMError(
`You cannot update relations of multiple entities with the same related object. Provide a single entity into .of method.`,
);
const of = this.expressionMap.of;
const updateSet = relation.inverseRelation!.joinColumns.reduce((updateSet, joinColumn) => {
const relationValue = ObjectUtils.isObject(of)
? joinColumn.referencedColumn!.getEntityValue(of)
: of;
joinColumn.setEntityValue(updateSet, relationValue);
return updateSet;
}, {} as any);
if (!value || (Array.isArray(value) && !value.length)) return;
await this.queryBuilder
.createQueryBuilder()
.update(relation.inverseEntityMetadata.target)
.set(updateSet)View on GitHub (pinned to 5ac6606e81)
Solutions
- Loop and call per-parent: for (const u of users) await qb.relation(User,'photos').of(u).add(photo).
- Restructure as a direct update on the inverse entity with an In(...) condition when bulk is required.
- Validate that .of receives a single object before constructing the relation call.
Example fix
// before await qb.relation(User,'photos').of(users).set(photo); // users is an array // after for (const u of users) await qb.relation(User,'photos').of(u).set(photo);
Defensive patterns
Strategy: validation
Validate before calling
function requireSingleOf(qb: any, parent: unknown) {
if (Array.isArray(parent)) throw new Error('One-to-many/inverse-one-to-one update requires a single parent in .of()');
qb.of(parent);
} Type guard
function isSingleParent(value: unknown): boolean { return !Array.isArray(value) && value != null; } Prevention
- Type helper signatures so .of only accepts a single entity for one-to-many/inverse-one-to-one relations.
- Bulk-update via direct manager.update(target, In(ids), partial) instead of relation API.
When it happens
Trigger: qb.relation(User,'photos').of([user1, user2]).set(photo) or .add(photo) — the parent side is plural for a one-to-many/inverse-one-to-one relation.
Common situations: Bulk helpers that pass arrays uniformly to all relation calls; refactoring a single-parent call into a loop but accidentally passing the array to .of.
Related errors
- Cannot save user <${this.email}>: Provided email is invalid
- Wrong driver: "${driverType}" given. Supported drivers are:
- Driver not Connected
- To use streams you should install pg-query-stream package. P
- Postgres package has not been found installed. Try to instal
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/59de944b05e7f0b4.
Report an issue: GitHub.