dbt run failed: column reference is ambiguous" model
Fixes ambiguous column errors in dbt models by qualifying the duplicated column with its table alias or selecting columns explicitly. Use when dbt run fails with an ambiguous column reference. Not for missing-column errors, which name a column that does not exist at all.
TL;DR
Two tables in a join both have the same column name, and the query references it without saying which table. Qualify the column (orders.customer_id), or replace select * with an explicit column list. Then rerun the model.
Error
"dbt run failed: column reference is ambiguous" modelSteps
- Run
dbt compile --select [MODEL NAME]and open the compiled SQL. Expected: you see the join and the unqualified column. - Find which joined tables both contain the named column. Expected: you identify the two (or more) sources of the duplicate.
- Qualify every reference to that column with the table alias, or rewrite the select list to name each column explicitly with its table. Expected: no bare references to the duplicated name remain.
- Avoid
select *across joins; list the columns you need. Expected: the select list is explicit and unambiguous. - Run
dbt run --select [MODEL NAME]. Expected: the model builds cleanly.
When to use
dbt runfails with "column reference is ambiguous".- You just added a join to a model that previously worked.
When not to use
- The error says the column does not exist (a missing-column problem).
- The ambiguity is inside a macro-generated fragment (fix the macro's select list).
Tool compatibility
- dbt Core 1.0 and later, all adapters. Name resolution rules come from the warehouse.
Variant phrasings
Column 'customer_id' in field list is ambiguous
The MySQL-family wording of the same error.
Ambiguous column after adding a second join to the same table
Self-joins need distinct aliases for each instance of the table.
Why it happens
SQL requires every column reference to resolve to exactly one table. When two tables in scope share a column name, an unqualified reference is ambiguous and the warehouse rejects the query.
Edge cases
select *plus a join is the most common trigger; explicit column lists prevent it permanently.- CTEs that select the same column name from different branches collide when joined; alias inside the CTE.
- dbt's
starmacro and similar helpers can reintroduceselect *; check their output in compiled SQL.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_uehy31gjfV-v2k-RXoVTkw