{"record":{"id":"9a37d65cabfdff1e","repo":"n8n-io/n8n","slug":"cannot-load-entity-because-only-one-primary-key-wa","errorCode":null,"errorMessage":"Cannot load entity because only one primary key was specified, however entity contains multiple primary keys","messagePattern":"Cannot load entity because only one primary key was specified, however entity contains multiple primary keys","errorType":"exception","errorClass":"TypeORMError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/query-builder/RelationQueryBuilder.ts","lineNumber":184,"sourceCode":"\n\t/**\n\t * Loads a single entity (relational) from the relation.\n\t * You can also provide id of relational entity to filter by.\n\t */\n\tasync loadOne<T = any>(): Promise<T | undefined> {\n\t\treturn this.loadMany<T>().then((results) => results[0]);\n\t}\n\n\t/**\n\t * Loads many entities (relational) from the relation.\n\t * You can also provide ids of relational entities to filter by.\n\t */\n\tasync loadMany<T = any>(): Promise<T[]> {\n\t\tlet of = this.expressionMap.of;\n\t\tif (!ObjectUtils.isObject(of)) {\n\t\t\tconst metadata = this.expressionMap.mainAlias!.metadata;\n\t\t\tif (metadata.hasMultiplePrimaryKeys)\n\t\t\t\tthrow new TypeORMError(\n\t\t\t\t\t`Cannot load entity because only one primary key was specified, however entity contains multiple primary keys`,\n\t\t\t\t);\n\n\t\t\tof = metadata.primaryColumns[0].createValueMap(of);\n\t\t}\n\n\t\treturn this.connection.relationLoader.load(\n\t\t\tthis.expressionMap.relationMetadata,\n\t\t\tof,\n\t\t\tthis.queryRunner,\n\t\t);\n\t}\n}\n","sourceCodeStart":166,"sourceCodeEnd":198,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/query-builder/RelationQueryBuilder.ts#L166-L198","documentation":"RelationQueryBuilder.loadMany accepts a scalar id in .of() only when the entity has a single primary key. When ObjectUtils.isObject(of) is false and metadata.hasMultiplePrimaryKeys is true, it cannot decide which PK the scalar refers to, so it throws TypeORMError rather than guessing.","triggerScenarios":"qb.relation(...).of(42).loadMany() (or loadOne) on an entity whose @PrimaryColumn set has more than one column; passing a bare id from a route param for a composite-PK entity.","commonSituations":"Entity migrated to composite PKs (e.g. adding tenantId to the PK) without updating callers that pass a single id; junction-table entities that are composite by design.","solutions":["Pass the full PK map: .of({ tenantId, id }).loadMany().","If only one id is available, look up the composite map first via the entity repository.","Add a type guard on the public helper that wraps loadMany so callers cannot pass a scalar for composite-PK entities."],"exampleFix":"// before\nawait qb.relation(Membership,'roles').of(membershipId).loadMany(); // composite PK\n// after\nawait qb.relation(Membership,'roles').of({ tenantId, membershipId }).loadMany();","handlingStrategy":"type-guard","validationCode":"import { DataSource } from 'typeorm';\n\nfunction requireCompositeOf(ds: DataSource, target: Function, of: unknown) {\n  const meta = ds.getMetadata(target);\n  if (meta.hasMultiplePrimaryKeys && (typeof of !== 'object' || of === null))\n    throw new Error(`Entity ${meta.targetName} has composite PK; pass .of({${meta.primaryColumns.map(c => c.propertyName).join(',')}})`);\n}","typeGuard":"function isPkMap(value: unknown): value is Record<string, unknown> {\n  return typeof value === 'object' && value !== null;\n}","tryCatchPattern":null,"preventionTips":["Tag composite-PK entities in a registry and route their relation loads through a helper that requires a map.","Document composite PKs prominently on the entity class."],"tags":["typeorm","relation-query-builder","load","composite-key"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}