drizzle-team/drizzle-orm · error · Error
You tried to reference "${prop}" field from a subquery, whic
Error message
You tried to reference "${prop}" field from a subquery, which is a raw SQL field, but it doesn't have an alias declared. Please add an alias to the field using ".as('alias')" method. What it means
SelectionProxyHandler.get() throws when you reference a property of a subquery/view selection that resolves to a raw SQL expression (instance of SQL, not SQL.Aliased) and the handler's sqlBehavior is 'error'. Raw SQL selections must be aliased via .as('name') so the proxy can expose them by name; without an alias there is no name to reference.
Source
Thrown at drizzle-orm/src/selection-proxy.ts:95
const value: unknown = columns[prop as keyof typeof columns];
if (is(value, SQL.Aliased)) {
// Never return the underlying SQL expression for a field previously selected in a subquery
if (this.config.sqlAliasedBehavior === 'sql' && !value.isSelectionField) {
return value.sql;
}
const newValue = value.clone();
newValue.isSelectionField = true;
return newValue;
}
if (is(value, SQL)) {
if (this.config.sqlBehavior === 'sql') {
return value;
}
throw new Error(
`You tried to reference "${prop}" field from a subquery, which is a raw SQL field, but it doesn't have an alias declared. Please add an alias to the field using ".as('alias')" method.`,
);
}
if (is(value, Column)) {
if (this.config.alias) {
return new Proxy(
value,
new ColumnAliasProxyHandler(
new Proxy(
value.table,
new TableAliasProxyHandler(this.config.alias, this.config.replaceOriginalName ?? false),
),
),
);
}
return value;
}View on GitHub (pinned to b7862528fd)
Solutions
- Add .as('alias') to every raw SQL field in the subquery/view selection: { count: sql`COUNT(*)`.as('count') }.
- If you intend to reference the raw expression itself, use sql`...` directly in the outer query rather than going through the selection proxy.
- Use the column's actual aliased name when accessing the field.
Example fix
// before (throws: raw SQL without alias)
const sq = db.$with('sq').as((qb) =>
qb.select({ total: sql`COUNT(*)` }).from(orders),
);
const rows = await db.with(sq).select({ t: sq.total }).from(sq);
// after
const sq = db.$with('sq').as((qb) =>
qb.select({ total: sql`COUNT(*)`.as('total') }).from(orders),
); Defensive patterns
Strategy: validation
Validate before calling
// Ensure raw SQL fields in subquery/view selections are aliased.
import { SQL } from 'drizzle-orm/sql/sql';
import { is } from 'drizzle-orm/entity';
function ensureRawSqlAliased(selection: Record<string, unknown>) {
for (const [name, v] of Object.entries(selection)) {
if (is(v, SQL) && !(v as any).isAliased) {
throw new Error(`Raw SQL field "${name}" needs .as('${name}')`);
}
}
} Type guard
import { SQL } from 'drizzle-orm/sql/sql';
import { is } from 'drizzle-orm/entity';
function isUnaliasedSql(v: unknown): boolean {
return is(v, SQL) && !(v as any).isAliased;
} Try / catch
try {
const rows = await db.with(sq).select({ t: sq.total }).from(sq);
} catch (e) {
if (e instanceof Error && /raw SQL field, but it doesn't have an alias/.test(e.message)) {
// re-define the subquery field with .as('alias')
} else throw e;
} Prevention
- Always alias raw SQL in subqueries/views: { count: sql`COUNT(*)`.as('count') }.
- Lint schema files for sql`...` usages inside selections that lack .as().
- Prefer Drizzle's aggregate helpers (e.g., count()) which alias automatically.
When it happens
Trigger: Selecting sql`...` (raw expression) inside a subquery or view without .as('alias'), then accessing that field by name through the selection proxy. Using db.$with('name').as(qb => ({ field: sql`...` })) and later referencing the field. Creating a view with raw SQL columns and querying its fields.
Common situations: Building CTEs or subqueries with computed columns (e.g., sql`COUNT(*)`) and forgetting the alias. Migrating raw SQL selects into Drizzle's query builder.
Related errors
- Alias "${tableName}" is already used in this query
- Alias "${tableName}" is already used in this query
- Alias "${tableName}" is already used in this query
- Alias "${tableName}" is already used in this query
- Alias "${tableName}" is already used in this query
AI-assisted analysis of drizzle-team/drizzle-orm@b7862528fd (2026-08-03).
Data as JSON: /data/errors/62ff7aba117976b9.json.
Report an issue: GitHub.