{"id":"6dbdffe3c5293345","repo":"drizzle-team/drizzle-orm","slug":"alias-tablename-is-already-used-in-this-query-6dbdff","errorCode":null,"errorMessage":"Alias \"${tableName}\" is already used in this query","messagePattern":"Alias \"(.+?)\" is already used in this query","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"drizzle-orm/src/pg-core/query-builders/update.ts","lineNumber":415,"sourceCode":"\t\tif (is(table, PgTable)) {\n\t\t\treturn table[Table.Symbol.Columns];\n\t\t} else if (is(table, Subquery)) {\n\t\t\treturn table._.selectedFields;\n\t\t}\n\t\treturn table[ViewBaseConfig].selectedFields;\n\t}\n\n\tprivate createJoin<TJoinType extends JoinType>(\n\t\tjoinType: TJoinType,\n\t): PgUpdateJoinFn<this, TDynamic, TJoinType> {\n\t\treturn ((\n\t\t\ttable: PgTable | Subquery | PgViewBase | SQL,\n\t\t\ton: ((updateTable: TTable, from: TFrom) => SQL | undefined) | SQL | undefined,\n\t\t) => {\n\t\t\tconst tableName = getTableLikeName(table);\n\n\t\t\tif (typeof tableName === 'string' && this.config.joins.some((join) => join.alias === tableName)) {\n\t\t\t\tthrow new Error(`Alias \"${tableName}\" is already used in this query`);\n\t\t\t}\n\n\t\t\tif (typeof on === 'function') {\n\t\t\t\tconst from = this.config.from && !is(this.config.from, SQL)\n\t\t\t\t\t? this.getTableLikeFields(this.config.from)\n\t\t\t\t\t: undefined;\n\t\t\t\ton = on(\n\t\t\t\t\tnew Proxy(\n\t\t\t\t\t\tthis.config.table[Table.Symbol.Columns],\n\t\t\t\t\t\tnew SelectionProxyHandler({ sqlAliasedBehavior: 'sql', sqlBehavior: 'sql' }),\n\t\t\t\t\t) as any,\n\t\t\t\t\tfrom && new Proxy(\n\t\t\t\t\t\tfrom,\n\t\t\t\t\t\tnew SelectionProxyHandler({ sqlAliasedBehavior: 'sql', sqlBehavior: 'sql' }),\n\t\t\t\t\t) as any,\n\t\t\t\t);\n\t\t\t}\n","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/drizzle-team/drizzle-orm/blob/b7862528fd8fc39bc2653a6c18dad7c1f4e68d10/drizzle-orm/src/pg-core/query-builders/update.ts#L397-L433","documentation":"PgUpdate.createJoin (update.ts:414) mirrors the select alias guard: it compares getTableLikeName(table) against existing join aliases in config.joins and throws on a duplicate. UPDATE...FROM in Postgres needs unique aliases for each referenced relation, so a repeat alias is rejected before SQL is built.","triggerScenarios":"Calling .from()/leftJoin()/innerJoin() on an update with a table or subquery whose alias was already used by the base table or a previous join; self-referential updates referencing the same table twice.","commonSituations":"Update-with-join patterns referencing the same lookup table twice; dynamic update builders appending joins without alias tracking; aliasing a subquery to collide with the target table.","solutions":["Alias the second reference differently via a subquery (db.$with('alias').as(...)).","For self-joins on the target table, use a distinct alias for the secondary reference.","Track used aliases in dynamic builders and synthesize unique names."],"exampleFix":"// before\ndb.update(t).set({...}).from(lookup).where(...)\n  .leftJoin(lookup, eq(lookup.id, t.lookupId)); // 'lookup' twice\n\n// after\nconst l2 = db.$with('l2').as(db.select().from(lookup));\ndb.update(t).set({...}).with(l2).from(lookup).leftJoin(l2, eq(l2.id, t.otherId)).where(...);","handlingStrategy":"validation","validationCode":"function buildUpdateJoin(db: Db, target: PgTable, joins: { table: PgTable | SQL; on: SQL }[]) {\n  const used = new Set<string>();\n  let q = db.update(target).set({}).from(joins[0].table);\n  used.add(String(getTableLikeName(joins[0].table)));\n  for (const j of joins.slice(1)) {\n    const alias = getTableLikeName(j.table);\n    if (typeof alias === 'string' && used.has(alias)) {\n      throw new Error(`Alias \"${alias}\" already used in update`);\n    }\n    if (typeof alias === 'string') used.add(alias);\n    q = (q as any).leftJoin(j.table, j.on);\n  }\n  return q;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Track aliases when building update-with-join dynamically.","Alias repeated references via $with(...).as(...).","Avoid reusing the target table name as a join alias."],"tags":["update","join","alias","validation"],"analyzedSha":"b7862528fd8fc39bc2653a6c18dad7c1f4e68d10","analyzedAt":"2026-08-03T18:11:14.318Z","schemaVersion":2}