drizzle-team/drizzle-orm · error · Error
Alias " " is already used in this query
Error message
Alias "${tableName}" is already used in this query What it means
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.
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.
Example fix
// before
db.update(accounts).set({ total: sql`children.amount` })
.from(accounts.as('children'))
.leftJoin(accounts.as('children'), ...); // 'children' twice
// after
db.update(accounts).set({ total: sql`children.amount` })
.from(accounts.as('children'))
.leftJoin(accounts.as('siblings'), ...); Defensive patterns
Strategy: validation
Validate before calling
function assertUniqueUpdateAlias(joins, alias) {
if (joins.some((j) => j.alias === alias)) {
throw new Error(`Alias ${alias} already used in update`);
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Alias " " is already used in this query
- Alias " " is already used in this query
- Alias " " is already used in this query
- Alias " " is already used in this query
- Alias " " is already used in this query
AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03).
Data as JSON: /api/errors/54baf02a7381a919.
Report an issue: GitHub.
Appendix: source
Thrown at drizzle-orm/src/sqlite-core/query-builders/update.ts:272
from<TFrom extends SQLiteTable | Subquery | SQLiteViewBase | SQL>(
source: TFrom,
): SQLiteUpdateWithJoins<this, TDynamic, TFrom> {
this.config.from = source;
return this as any;
}
private createJoin<TJoinType extends JoinType>(
joinType: TJoinType,
): SQLiteUpdateJoinFn<this> {
return ((
table: SQLiteTable | Subquery | SQLiteViewBase | SQL,
on: ((updateTable: TTable, from: TFrom) => SQL | undefined) | SQL | undefined,
) => {
const tableName = getTableLikeName(table);
if (typeof tableName === 'string' && this.config.joins.some((join) => join.alias === tableName)) {
throw new Error(`Alias "${tableName}" is already used in this query`);
}
if (typeof on === 'function') {
const from = this.config.from
? is(table, SQLiteTable)
? table[Table.Symbol.Columns]
: is(table, Subquery)
? table._.selectedFields
: is(table, SQLiteViewBase)
? table[ViewBaseConfig].selectedFields
: undefined
: undefined;
on = on(
new Proxy(
this.config.table[Table.Symbol.Columns],
new SelectionProxyHandler({ sqlAliasedBehavior: 'sql', sqlBehavior: 'sql' }),
) as any,
from && new Proxy(View on GitHub (pinned to b7862528fd)