drizzle-team/drizzle-orm · error · Error

Alias "${tableName}" 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.

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)

Solutions

  1. Give each joined instance a unique alias via .as('aliasN').
  2. Rename the conflicting FROM/join alias string.
  3. 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

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


AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03). Data as JSON: /data/errors/54baf02a7381a919.json. Report an issue: GitHub.