{"id":"62ff7aba117976b9","repo":"drizzle-team/drizzle-orm","slug":"you-tried-to-reference-prop-field-from-a-subq","errorCode":null,"errorMessage":"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.","messagePattern":"You tried to reference \"(.+?)\" 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\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"drizzle-orm/src/selection-proxy.ts","lineNumber":95,"sourceCode":"\t\tconst value: unknown = columns[prop as keyof typeof columns];\n\n\t\tif (is(value, SQL.Aliased)) {\n\t\t\t// Never return the underlying SQL expression for a field previously selected in a subquery\n\t\t\tif (this.config.sqlAliasedBehavior === 'sql' && !value.isSelectionField) {\n\t\t\t\treturn value.sql;\n\t\t\t}\n\n\t\t\tconst newValue = value.clone();\n\t\t\tnewValue.isSelectionField = true;\n\t\t\treturn newValue;\n\t\t}\n\n\t\tif (is(value, SQL)) {\n\t\t\tif (this.config.sqlBehavior === 'sql') {\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t\tthrow new Error(\n\t\t\t\t`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.`,\n\t\t\t);\n\t\t}\n\n\t\tif (is(value, Column)) {\n\t\t\tif (this.config.alias) {\n\t\t\t\treturn new Proxy(\n\t\t\t\t\tvalue,\n\t\t\t\t\tnew ColumnAliasProxyHandler(\n\t\t\t\t\t\tnew Proxy(\n\t\t\t\t\t\t\tvalue.table,\n\t\t\t\t\t\t\tnew TableAliasProxyHandler(this.config.alias, this.config.replaceOriginalName ?? false),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn value;\n\t\t}","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/drizzle-team/drizzle-orm/blob/b7862528fd8fc39bc2653a6c18dad7c1f4e68d10/drizzle-orm/src/selection-proxy.ts#L77-L113","documentation":"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.","triggerScenarios":"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.","commonSituations":"Building CTEs or subqueries with computed columns (e.g., sql`COUNT(*)`) and forgetting the alias. Migrating raw SQL selects into Drizzle's query builder.","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."],"exampleFix":"// before (throws: raw SQL without alias)\nconst sq = db.$with('sq').as((qb) =>\n  qb.select({ total: sql`COUNT(*)` }).from(orders),\n);\nconst rows = await db.with(sq).select({ t: sq.total }).from(sq);\n\n// after\nconst sq = db.$with('sq').as((qb) =>\n  qb.select({ total: sql`COUNT(*)`.as('total') }).from(orders),\n);","handlingStrategy":"validation","validationCode":"// Ensure raw SQL fields in subquery/view selections are aliased.\nimport { SQL } from 'drizzle-orm/sql/sql';\nimport { is } from 'drizzle-orm/entity';\n\nfunction ensureRawSqlAliased(selection: Record<string, unknown>) {\n  for (const [name, v] of Object.entries(selection)) {\n    if (is(v, SQL) && !(v as any).isAliased) {\n      throw new Error(`Raw SQL field \"${name}\" needs .as('${name}')`);\n    }\n  }\n}","typeGuard":"import { SQL } from 'drizzle-orm/sql/sql';\nimport { is } from 'drizzle-orm/entity';\n\nfunction isUnaliasedSql(v: unknown): boolean {\n  return is(v, SQL) && !(v as any).isAliased;\n}","tryCatchPattern":"try {\n  const rows = await db.with(sq).select({ t: sq.total }).from(sq);\n} catch (e) {\n  if (e instanceof Error && /raw SQL field, but it doesn't have an alias/.test(e.message)) {\n    // re-define the subquery field with .as('alias')\n  } else throw e;\n}","preventionTips":["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."],"tags":["subquery","view","raw-sql","alias","selection-proxy"],"analyzedSha":"b7862528fd8fc39bc2653a6c18dad7c1f4e68d10","analyzedAt":"2026-08-03T18:11:14.318Z","schemaVersion":2}