n8n-io/n8n · error · TypeORMError

Junction property is not defined.

Error message

Junction property is not defined.

What it means

JoinAttribute.junctionAlias getter, after confirming this.relation exists, throws if entityOrProperty is not a string. The junction alias is derived by splitting entityOrProperty on '.' (aliasProperty = entityOrProperty.substr(0, indexOf('.'))); a non-string target (entity class, subquery builder, or object) has no property string to derive the alias from.

Source

Thrown at packages/@n8n/typeorm/src/query-builder/JoinAttribute.ts:222

            // and its target is a string name (scenario when plain old javascript is used or entity schema is loaded from files)
            const metadata = this.connection.entityMetadatas.find(metadata => metadata.name === this.entityOrProperty);
            if (metadata)
                return metadata;

            // check if we have entity with such table name, and use its metadata if found
            return this.connection.entityMetadatas.find(metadata => metadata.tableName === this.entityOrProperty);
        }*/
	}

	/**
	 * Generates alias of junction table, whose ids we get.
	 */
	get junctionAlias(): string {
		if (!this.relation) {
			throw new TypeORMError(`Cannot get junction table for join without relation.`);
		}
		if (typeof this.entityOrProperty !== 'string') {
			throw new TypeORMError(`Junction property is not defined.`);
		}

		const aliasProperty = this.entityOrProperty.substr(0, this.entityOrProperty.indexOf('.'));

		if (this.relation.isOwning) {
			return DriverUtils.buildAlias(
				this.connection.driver,
				undefined,
				aliasProperty,
				this.alias.name,
			);
		} else {
			return DriverUtils.buildAlias(
				this.connection.driver,
				undefined,
				this.alias.name,
				aliasProperty,
			);

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Pass a string property path ('alias.relation') when the join needs junction alias derivation.
  2. If using the public API, prefer leftJoin('alias.relation', 'joinAlias') string form for many-to-many joins.
  3. Audit custom JoinAttribute construction to ensure entityOrProperty is a string for relation joins.
  4. Report as an internal bug if it surfaces from plain repository/QueryBuilder usage.

Example fix

// before — non-string join target in custom builder
qb.innerJoin(userEntityClass, 'ue', 'ue.id = m.userId');

// after — string property-path form
qb.innerJoin('member.user', 'ue');
Defensive patterns

Strategy: validation

Validate before calling

function isStringJoinTarget(t: unknown): t is string {
  return typeof t === 'string' && t.includes('.');
}
if (!isStringJoinTarget(entityOrProperty)) throw new Error('join target must be a string property path "alias.relation" for relation joins');

Type guard

function isStringPropertyPath(t: unknown): t is string {
  return typeof t === 'string' && /^[A-Za-z0-9_]+\.[A-Za-z0-9_.]+$/.test(t);
}

Prevention

When it happens

Trigger: A JoinAttribute constructed with a non-string entityOrProperty (e.g. an entity class function or a SelectQueryBuilder) reaching the junctionAlias code path. This is typically an internal assertion failure rather than a direct API misuse.

Common situations: Passing an entity class reference instead of the string alias when constructing a many-to-many join. Internal TypeORM refactors that change entityOrProperty shape. Custom QueryBuilder extensions building JoinAttributes with object targets.

Related errors


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