n8n-io/n8n · error · TypeORMError
Value to be set into the relation must be a map of relation
Error message
Value to be set into the relation must be a map of relation ids, for example: .set({ firstName: "...", lastName: "..." }) What it means
Inside RelationQueryBuilder.set, when relation.joinColumns.length > 1 (a composite FK), the value argument must be an object map with at least one key per join column. If ObjectUtils.isObject(value) is false or the key count is less than the join-column count, TypeORM throws TypeORMError showing the expected shape .set({ firstName:'...', lastName:'...' }).
Source
Thrown at packages/@n8n/typeorm/src/query-builder/RelationQueryBuilder.ts:67
// todo: move this check before relation query builder creation?
throw new TypeORMError(
`Entity whose relation needs to be set is not set. Use .of method to define whose relation you want to set.`,
);
if (relation.isManyToMany || relation.isOneToMany)
throw new TypeORMError(
`Set operation is only supported for many-to-one and one-to-one relations. ` +
`However given "${relation.propertyPath}" has ${relation.relationType} relation. ` +
`Use .add() method instead.`,
);
// if there are multiple join columns then user must send id map as "value" argument. check if he really did it
if (
relation.joinColumns &&
relation.joinColumns.length > 1 &&
(!ObjectUtils.isObject(value) || Object.keys(value).length < relation.joinColumns.length)
)
throw new TypeORMError(
`Value to be set into the relation must be a map of relation ids, for example: .set({ firstName: "...", lastName: "..." })`,
);
const updater = new RelationUpdater(this, this.expressionMap);
return updater.update(value);
}
/**
* Adds (binds) given value to entity relation.
* Value can be entity, entity id or entity id map (if entity has composite ids).
* Value also can be array of entities, array of entity ids or array of entity id maps (if entity has composite ids).
* Works only for many-to-many and one-to-many relations.
* For many-to-one and one-to-one use #set method instead.
*/
async add(value: any | any[]): Promise<void> {
if (Array.isArray(value) && value.length === 0) return;
const relation = this.expressionMap.relationMetadata;View on GitHub (pinned to 5ac6606e81)
Solutions
- Pass a map covering every referenced column: qb.relation(...).of(u).set({ tenantId, userId }).
- Inspect relation.joinColumns (or its referencedColumn.propertyName) at design time to enumerate the required keys.
- If the caller only has one id, fetch the related entity first and pass its composite id map.
Example fix
// before
qb.relation(Membership,'user').of(m).set(userId); // join uses (tenantId,userId)
// after
qb.relation(Membership,'user').of(m).set({ tenantId, userId }); Defensive patterns
Strategy: type-guard
Validate before calling
import { DataSource } from 'typeorm';
function compositeKeys(ds: DataSource, target: Function, path: string): string[] {
const r = ds.getMetadata(target).findRelationWithPropertyPath(path)!;
return r.joinColumns.map((c: any) => c.referencedColumn!.propertyName);
}
// const keys = compositeKeys(ds, Membership, 'user');
// if (Object.keys(value).length < keys.length) throw new Error(`need keys ${keys.join(',')}`); Type guard
function isCompositeValueMap(value: unknown, keys: string[]): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && keys.every((k) => k in value);
} Prevention
- For composite-FK relations, document the required map shape in JSDoc on the helper.
- Validate the value shape at the API boundary with a schema (zod/joi).
- Never accept a bare id from user input for composite-key entities.
When it happens
Trigger: Calling .set(singleId) on a relation whose join uses composite keys (e.g. a relation keyed by (tenantId, userId)). Passing an array or a primitive where a partial-object map is required.
Common situations: Composite-key entities introduced after the call site was written; tenant-scoped tables where every relation carries tenantId in the FK; passing a bare id from a request param instead of {tenantId, userId}.
Related errors
- Cannot load entity because only one primary key was specifie
- Entity whose relation needs to be set is not set. Use .of me
- Set operation is only supported for many-to-one and one-to-o
- Add operation is only supported for many-to-many and one-to-
- Add operation is only supported for many-to-many and one-to-
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/b72e08bbe50627ab.
Report an issue: GitHub.