n8n-io/n8n · error · TypeORMError

Entity whose relation needs to be set is not set. Use .of me

Error message

Entity whose relation needs to be set is not set. Use .of method to define whose relation you want to set.

What it means

RelationQueryBuilder.set throws TypeORMError before touching the DB if this.expressionMap.of is unset. .of(entityOrId) is what binds the operation to a concrete parent row; without it TypeORM cannot know which row to update, so it refuses rather than issue an unbounded update.

Source

Thrown at packages/@n8n/typeorm/src/query-builder/RelationQueryBuilder.ts:50

	 * Sets entity (target) which relations will be updated.
	 */
	of(entity: any | any[]): this {
		this.expressionMap.of = entity;
		return this;
	}

	/**
	 * Sets entity relation's value.
	 * Value can be entity, entity id or entity id map (if entity has composite ids).
	 * Works only for many-to-one and one-to-one relations.
	 * For many-to-many and one-to-many relations use #add and #remove methods instead.
	 */
	async set(value: any): Promise<void> {
		const relation = this.expressionMap.relationMetadata;

		if (!this.expressionMap.of)
			// 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: "..." })`,

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Always chain .of() before .set(): qb.relation(Entity,'rel').of(parent).set(value).
  2. If the parent is dynamic, guard in application code: if (!parent?.id) throw new UserError('parent required') before building the relation call.
  3. Add a unit test asserting .of is set when the helper is invoked.

Example fix

// before
await qb.relation(User,'profile').set(profileId);
// after
await qb.relation(User,'profile').of(user).set(profileId);
Defensive patterns

Strategy: validation

Validate before calling

function requireOf<T>(qb: any, parent: T | undefined | null): T {
  if (parent == null) throw new Error('parent entity is required to .set() a relation');
  qb.of(parent);
  return parent;
}

Type guard

function hasOf(qb: any): boolean { return qb.expressionMap.of != null; }

Prevention

When it happens

Trigger: Calling qb.relation('User.profile').set(profile) and forgetting .of(user); calling .set() before .of() in the chain (note .of returns this so order matters only if you never call it).

Common situations: Helper that conditionally sets a relation and skips the .of() in an edge branch; refactor that moves .of() into a separate function which is not always invoked.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/c95682d3d40b4c05. Report an issue: GitHub.