{"record":{"id":"7161770944f281f8","repo":"n8n-io/n8n","slug":"cannot-use-given-entity-id-id-because-meta","errorCode":null,"errorMessage":"Cannot use given entity id \"${id}\" because \"${metadata.targetName}\" contains multiple primary columns, you must provide object in following form: ${JSON.stringify(objectExample)} as an id.","messagePattern":"Cannot use given entity id \"(.+?)\" because \"(.+?)\" contains multiple primary columns, you must provide object in following form: (.+?) as an id\\.","errorType":"exception","errorClass":"CannotCreateEntityIdMapError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/metadata/EntityMetadata.ts","lineNumber":615,"sourceCode":"\t * Returns true if it contains all of them, false if at least one of them is not defined.\n\t */\n\thasAllPrimaryKeys(entity: ObjectLiteral): boolean {\n\t\treturn this.primaryColumns.every((primaryColumn) => {\n\t\t\tconst value = primaryColumn.getEntityValue(entity);\n\t\t\treturn value !== null && value !== undefined;\n\t\t});\n\t}\n\n\t/**\n\t * Ensures that given object is an entity id map.\n\t * If given id is an object then it means its already id map.\n\t * If given id isn't an object then it means its a value of the id column\n\t * and it creates a new id map with this value and name of the primary column.\n\t */\n\tensureEntityIdMap(id: any): ObjectLiteral {\n\t\tif (ObjectUtils.isObject(id)) return id;\n\n\t\tif (this.hasMultiplePrimaryKeys) throw new CannotCreateEntityIdMapError(this, id);\n\n\t\treturn this.primaryColumns[0].createValueMap(id);\n\t}\n\n\t/**\n\t * Gets primary keys of the entity and returns them in a literal object.\n\t * For example, for Post{ id: 1, title: \"hello\" } where id is primary it will return { id: 1 }\n\t * For multiple primary keys it returns multiple keys in object.\n\t * For primary keys inside embeds it returns complex object literal with keys in them.\n\t */\n\tgetEntityIdMap(entity: ObjectLiteral | undefined): ObjectLiteral | undefined {\n\t\tif (!entity) return undefined;\n\n\t\treturn EntityMetadata.getValueMap(entity, this.primaryColumns, {\n\t\t\tskipNulls: true,\n\t\t});\n\t}\n","sourceCodeStart":597,"sourceCodeEnd":633,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/metadata/EntityMetadata.ts#L597-L633","documentation":"Thrown by EntityMetadata.ensureEntityIdMap when you pass a scalar id (number/string) to a repository operation on an entity that has more than one primary-key column. TypeORM cannot decide which of the composite PK columns the scalar belongs to, so it refuses to build the id map and prints the exact object shape it expects (e.g. {tenantId: 1, id: 2}). The error class is CannotCreateEntityIdMapError; it triggers only when ObjectUtils.isObject(id) is false AND this.hasMultiplePrimaryKeys is true.","triggerScenarios":"Calling repo.findOne(5), repo.delete(5), or any method that ultimately routes a raw id through ensureEntityIdMap on an entity whose metadata.primaryColumns.length > 1. The branch `if (this.hasMultiplePrimaryKeys) throw new CannotCreateEntityIdMapError(this, id)` is hit.","commonSituations":"Entities with composite primary keys (multi-tenant designs using @PrimaryColumn on both tenantId and id), or junction entities promoted to full entities. Switching a single-PK entity to composite PK but forgetting to update existing findOne(id) call sites.","solutions":["Pass an id-map object instead of a scalar: repo.findOne({ where: { tenantId, id } }) using the exact key names from the printed objectExample.","If you intended single-column PK, audit the entity and remove the extra @PrimaryColumn so metadata.primaryColumns has length 1.","Centralize id construction in a helper (buildPk(tenantId, id)) so every call site produces the correct object shape."],"exampleFix":"// before\nconst user = await userRepo.findOne(5);\n\n// after (composite PK)\nconst user = await userRepo.findOne({\n  where: { tenantId: ctx.tenantId, id: 5 },\n});","handlingStrategy":"type-guard","validationCode":"function isCompositePk(\n  target: Function | EntitySchema<any>,\n  dataSource: DataSource,\n): boolean {\n  const meta = dataSource.getMetadata(target);\n  return meta.primaryColumns.length > 1;\n}\n\n// before calling findOne(id)\nif (isCompositePk(User, dataSource)) {\n  return userRepo.findOne({ where: { tenantId, id } });\n}\nreturn userRepo.findOne(id);","typeGuard":"type ScalarId = string | number;\ntype IdMap = Record<string, unknown>;\nfunction isIdMap(id: unknown): id is IdMap {\n  return typeof id === 'object' && id !== null && !Array.isArray(id);\n}\nfunction asFindOptionsId(id: ScalarId | IdMap, pkColumns: string[]): IdMap {\n  if (isIdMap(id)) return id;\n  if (pkColumns.length !== 1) {\n    throw new Error('Scalar id supplied for composite PK; pass an object keyed by ' + pkColumns.join(','));\n  }\n  return { [pkColumns[0]]: id };\n}","tryCatchPattern":"try {\n  await userRepo.findOne(id);\n} catch (err) {\n  if (err instanceof CannotCreateEntityIdMapError) {\n    // re-issue with the printed object shape\n    throw err;\n  }\n  throw err;\n}","preventionTips":["Wrap every repository lookup behind a helper that inspects metadata.primaryColumns.length and requires an object id for composite keys.","Codify the composite-PK shape in a branded type so callers cannot pass a scalar by accident.","Add a unit test that asserts the entity's PK column count and the expected id-map shape."],"tags":["composite-key","primary-key","find","runtime"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}