{"id":"54baf02a7381a919","repo":"drizzle-team/drizzle-orm","slug":"alias-tablename-is-already-used-in-this-query-54baf0","errorCode":null,"errorMessage":"Alias \"${tableName}\" is already used in this query","messagePattern":"Alias \"(.+?)\" is already used in this query","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"drizzle-orm/src/sqlite-core/query-builders/update.ts","lineNumber":272,"sourceCode":"\n\tfrom<TFrom extends SQLiteTable | Subquery | SQLiteViewBase | SQL>(\n\t\tsource: TFrom,\n\t): SQLiteUpdateWithJoins<this, TDynamic, TFrom> {\n\t\tthis.config.from = source;\n\t\treturn this as any;\n\t}\n\n\tprivate createJoin<TJoinType extends JoinType>(\n\t\tjoinType: TJoinType,\n\t): SQLiteUpdateJoinFn<this> {\n\t\treturn ((\n\t\t\ttable: SQLiteTable | Subquery | SQLiteViewBase | 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\n\t\t\t\t\t? is(table, SQLiteTable)\n\t\t\t\t\t\t? table[Table.Symbol.Columns]\n\t\t\t\t\t\t: is(table, Subquery)\n\t\t\t\t\t\t? table._.selectedFields\n\t\t\t\t\t\t: is(table, SQLiteViewBase)\n\t\t\t\t\t\t? table[ViewBaseConfig].selectedFields\n\t\t\t\t\t\t: undefined\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(","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/drizzle-team/drizzle-orm/blob/b7862528fd8fc39bc2653a6c18dad7c1f4e68d10/drizzle-orm/src/sqlite-core/query-builders/update.ts#L254-L290","documentation":"Thrown when joining a table in a SQLite UPDATE (update.ts:272) whose alias already matches a join registered earlier in the same UPDATE statement (UPDATE ... FROM ... JOIN). Drizzle keeps the update's joins list and rejects duplicate aliases to keep generated SQL unambiguous.","triggerScenarios":"db.update(t).set({...}).from(other).leftJoin(t.as('x')) after 'x' is already in the FROM/joins; self-referential update joining the same table twice without distinct aliases; joining a subquery whose alias collides with an existing one.","commonSituations":"Self-join updates (e.g. update parent stats from child rows of the same table); alias collisions after renaming; copy-pasting a join into an update builder.","solutions":["Give each joined instance a unique alias via .as('aliasN').","Rename the conflicting FROM/join alias string.","Check the joins list for duplicates before building."],"exampleFix":"// before\ndb.update(accounts).set({ total: sql`children.amount` })\n  .from(accounts.as('children'))\n  .leftJoin(accounts.as('children'), ...); // 'children' twice\n\n// after\ndb.update(accounts).set({ total: sql`children.amount` })\n  .from(accounts.as('children'))\n  .leftJoin(accounts.as('siblings'), ...);","handlingStrategy":"validation","validationCode":"function assertUniqueUpdateAlias(joins, alias) {\n  if (joins.some((j) => j.alias === alias)) {\n    throw new Error(`Alias ${alias} already used in update`);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Alias self-joined tables distinctly in UPDATE...FROM statements.","Track used aliases when chaining multiple joins on an update.","Give subquery joins explicit, unique alias strings."],"tags":["update","joins","alias","self-join"],"analyzedSha":"b7862528fd8fc39bc2653a6c18dad7c1f4e68d10","analyzedAt":"2026-08-03T18:11:14.318Z","schemaVersion":2}