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
- Pass a string property path ('alias.relation') when the join needs junction alias derivation.
- If using the public API, prefer leftJoin('alias.relation', 'joinAlias') string form for many-to-many joins.
- Audit custom JoinAttribute construction to ensure entityOrProperty is a string for relation joins.
- 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
- Use string property-path form ('alias.relation') for relation joins.
- Avoid passing entity classes or subquery builders where junction alias derivation is expected.
- Audit custom JoinAttribute construction for non-string targets.
- Treat this error as an internal bug if it arises from public API usage.
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
- Cannot get junction table for join without relation.
- Relation with property path ${this.relationPropertyPath} in
- Cannot find alias for relation at ${fullRelationPath}
- Weaviate store factory did not return an ExtendedWeaviateVec
- Internal error. Subject ${subject.metadata.targetName} must
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/e599e1b3e0c09017.
Report an issue: GitHub.