{"record":{"id":"f94e60be9a9fad05","repo":"n8n-io/n8n","slug":"cannot-get-junction-table-for-join-without-relatio","errorCode":null,"errorMessage":"Cannot get junction table for join without relation.","messagePattern":"Cannot get junction table for join without relation\\.","errorType":"exception","errorClass":"TypeORMError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/query-builder/JoinAttribute.ts","lineNumber":219,"sourceCode":"\t\t/*if (typeof this.entityOrProperty === \"string\") { // entityOrProperty is a custom table\n\n            // first try to find entity with such name, this is needed when entity does not have a target class,\n            // and its target is a string name (scenario when plain old javascript is used or entity schema is loaded from files)\n            const metadata = this.connection.entityMetadatas.find(metadata => metadata.name === this.entityOrProperty);\n            if (metadata)\n                return metadata;\n\n            // check if we have entity with such table name, and use its metadata if found\n            return this.connection.entityMetadatas.find(metadata => metadata.tableName === this.entityOrProperty);\n        }*/\n\t}\n\n\t/**\n\t * Generates alias of junction table, whose ids we get.\n\t */\n\tget junctionAlias(): string {\n\t\tif (!this.relation) {\n\t\t\tthrow new TypeORMError(`Cannot get junction table for join without relation.`);\n\t\t}\n\t\tif (typeof this.entityOrProperty !== 'string') {\n\t\t\tthrow new TypeORMError(`Junction property is not defined.`);\n\t\t}\n\n\t\tconst aliasProperty = this.entityOrProperty.substr(0, this.entityOrProperty.indexOf('.'));\n\n\t\tif (this.relation.isOwning) {\n\t\t\treturn DriverUtils.buildAlias(\n\t\t\t\tthis.connection.driver,\n\t\t\t\tundefined,\n\t\t\t\taliasProperty,\n\t\t\t\tthis.alias.name,\n\t\t\t);\n\t\t} else {\n\t\t\treturn DriverUtils.buildAlias(\n\t\t\t\tthis.connection.driver,\n\t\t\t\tundefined,","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/query-builder/JoinAttribute.ts#L201-L237","documentation":"JoinAttribute.junctionAlias getter throws when this.relation is falsy. Junction tables (the join table for @ManyToMany) only exist for relation-backed joins; a raw table or subquery join has no junction. Accessing junctionAlias on such a join is a programming error — the caller assumed a many-to-many relation where none exists.","triggerScenarios":"Internal TypeORM code path (e.g. relation loader, many-to-many persistence) calls joinAttribute.junctionAlias on a JoinAttribute whose relation getter returned undefined because the join target is not a relation. Reproduced by attempting many-to-many operations on a join that was built from a raw table or whose relation metadata failed to resolve.","commonSituations":"Mixing raw joins with relation-based many-to-many persistence on the same query. Entity misconfiguration where a @ManyToMany is missing the @JoinTable so relation resolution yields undefined. Custom query-builder extensions that assume junction presence.","solutions":["Ensure the @ManyToMany relation has a @JoinTable decorator so metadata resolution succeeds.","Avoid calling relation-dependent query-builder APIs on raw (non-relation) joins.","Verify the join target is a relation (joinAttribute.relation is truthy) before the code path that reads junctionAlias.","Re-check entity registration in the DataSource so relation metadata is populated."],"exampleFix":"// before — missing @JoinTable causes relation to resolve undefined\n@Entity()\nclass Team {\n  @ManyToMany(() => User)\n  members: User[]; // junctionAlias access later throws\n}\n\n// after\n@Entity()\nclass Team {\n  @ManyToMany(() => User)\n  @JoinTable()\n  members: User[];\n}","handlingStrategy":"type-guard","validationCode":"function isManyToManyRelation(rel: import('../metadata/RelationMetadata').RelationMetadata | undefined): boolean {\n  return !!rel && rel.relationType === 'many-to-many';\n}\nconst rel = entityMetadata.findRelationWithPropertyPath('members');\nif (!isManyToManyRelation(rel)) throw new Error('junction alias requires a many-to-many relation');","typeGuard":"function hasRelation(attr: { relation: unknown }): attr is { relation: import('../metadata/RelationMetadata').RelationMetadata } {\n  return attr.relation != null;\n}","tryCatchPattern":null,"preventionTips":["Decorate @ManyToMany relations with @JoinTable so metadata resolves.","Reserve junction-dependent APIs for relation-backed joins.","Verify relation metadata is loaded before many-to-many operations.","Ensure entities are registered in DataSource so metadata is populated."],"tags":["query-builder","join","many-to-many","junction","metadata"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}