{"record":{"id":"03af048b6d293116","repo":"n8n-io/n8n","slug":"table-is-not-part-of-this-query","errorCode":null,"errorMessage":"\"${table}\" is not part of this query","messagePattern":"\"(.+?)\" is not part of this query","errorType":"exception","errorClass":"TypeORMError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/find-options/FindOptionsUtils.ts","lineNumber":186,"sourceCode":"\n        if (options.lock) {\n            if (options.lock.mode === \"optimistic\") {\n                qb.setLock(options.lock.mode, options.lock.version);\n            } else if (\n                options.lock.mode === \"pessimistic_read\" ||\n                options.lock.mode === \"pessimistic_write\" ||\n                options.lock.mode === \"dirty_read\" ||\n                options.lock.mode === \"pessimistic_partial_write\" ||\n                options.lock.mode === \"pessimistic_write_or_fail\" ||\n                options.lock.mode === \"for_no_key_update\" ||\n                options.lock.mode === \"for_key_share\"\n            ) {\n                const tableNames = options.lock.tables ? options.lock.tables.map((table) => {\n                    const tableAlias = qb.expressionMap.aliases.find((alias) => {\n                        return alias.metadata.tableNameWithoutPrefix === table;\n                    });\n                    if (!tableAlias) {\n                        throw new TypeORMError(`\"${table}\" is not part of this query`);\n                    }\n                    return qb.escape(tableAlias.name);\n                }) : undefined;\n                qb.setLock(options.lock.mode, undefined, tableNames);\n            }\n        }\n\n        if (options.loadRelationIds === true) {\n            qb.loadAllRelationIds();\n\n        } else if (options.loadRelationIds instanceof Object) {\n            qb.loadAllRelationIds(options.loadRelationIds as any);\n        }\n\n        if (options.where)\n            qb.where(options.where);\n\n        if ((options as FindManyOptions<T>).skip)","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/find-options/FindOptionsUtils.ts#L168-L204","documentation":"When options.lock.tables is provided with a row-level locking mode (pessimistic_write, dirty_read, pessimistic_partial_write, pessimistic_write_or_fail, for_no_key_update, for_key_share), FindOptionsUtils looks up each table name in qb.expressionMap.aliases by metadata.tableNameWithoutPrefix. If no alias matches, it throws `\"${table}\" is not part of this query`.","triggerScenarios":"Locking tables that aren't joined or selected in the query (e.g. `lock: { tables: ['user'] }` on a query whose main alias is `Order` and never joins User); typo in the table name (camelCase vs snake); using the entity class name instead of the table name; locking a table after a refactor that removed the join.","commonSituations":"Adding pessimistic locking to a query without confirming the target table is part of the FROM/JOIN; switching naming strategy so tableNameWithoutPrefix changed; copy-pasting lock config between queries; locking a table that's only referenced via a subquery.","solutions":["Ensure each table listed in `lock.tables` is present as a join or the main alias in the query.","Use the table name (matching metadata.tableNameWithoutPrefix), not the class name.","If you only need to lock the main row, omit `tables` — TypeORM locks the main table by default.","Re-verify after refactoring joins that the locked tables are still part of the query."],"exampleFix":"// before - locking a table that isn't in the query\nawait repo.find({\n  where: { id },\n  lock: { mode: 'pessimistic_write', tables: ['user'] },\n});\n\n// after - lock the main alias, or join the table first\nawait repo.createQueryBuilder('order')\n  .leftJoinAndSelect('order.user', 'user')\n  .setLock('pessimistic_write', undefined, ['order', 'user'])\n  .getOne();","handlingStrategy":"validation","validationCode":"function validateLockTables(qb: import('@n8n/typeorm').QueryBuilder<any>, tables: string[]): void {\n  const known = qb.expressionMap.aliases.map(a => a.metadata?.tableNameWithoutPrefix).filter(Boolean);\n  for (const t of tables) {\n    if (!known.includes(t)) throw new Error(`lock table ${t} is not part of this query`);\n  }\n}\n// after building the query (with joins in place) but before getOne/getMany\nif (options.lock?.tables) validateLockTables(qb, options.lock.tables);","typeGuard":"function tableIsInQuery(qb: import('@n8n/typeorm').QueryBuilder<any>, table: string): boolean {\n  return qb.expressionMap.aliases.some(a => a.metadata?.tableNameWithoutPrefix === table);\n}","tryCatchPattern":null,"preventionTips":["Omit lock.tables to lock just the main alias.","Only list tables that appear in FROM or JOIN.","Use tableNameWithoutPrefix, not the class name.","Re-validate after refactoring joins."],"tags":["typeorm","locking","find-options","pessimistic"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}