# dbt: 'source' is undefined in staging model

## TL;DR

`'source' is undefined` is Jinja telling you the `source()` *function itself* is missing from the rendering context, not that your source is misnamed. dbt only injects `source()` into model, test, snapshot, and macro rendering contexts. The usual cause: the `{{ source(...) }}` call sits inside a `{% docs %}` block (docs blocks get a bare context that only provides `doc()`), or inside a macro or hook that is rendered outside a model. Move the `source()` call into the model SQL body and the error goes away.

```text
Compilation Error in model stg_orders (models/staging/stg_orders.sql)
  'source' is undefined
```

## Steps

### 1. Find the exact `source(` call that fails

Run the compile with debug output and see which file Jinja was rendering when it failed:

```bash
dbt compile --select stg_orders --debug 2>&1 | grep -B5 "is undefined" | head -40
```

Expected: a traceback naming a file and line. If it names a `.md` docs file, a `schema.yml`, or anything other than your model's `.sql` body, that location is the whole diagnosis.

### 2. Check whether the call is inside a `{% docs %}` block

Open the flagged file and look for `{% docs %}` / `{% enddocs %}` around the `{{ source(...) }}` call. Docs blocks render with a minimal context that only provides `doc()` — `source()` and `ref()` do not exist there.

If that is the case, replace the dynamic call with static text. Docs are rendered once as documentation; they cannot resolve warehouse relations:

```sql
{% docs stg_orders__table %}
This model reads from the raw orders table in the jaffle_shop source.
{% enddocs %}
```

Expected: no `{{ source(` calls remain inside docs blocks. Verify with:

```bash
grep -rn "{{ source(" models/staging/*.md models/staging/schema.yml | grep -i "docs" | head
```

### 3. Check macros and hooks

If the call is inside a macro, check every place that macro is invoked. A macro called from a model body has `source()`; the same macro called from a docs block or an `on-run-start` / `on-run-end` hook does not. Fix it by resolving the relation in the model and passing it in as an argument:

```sql
-- in the model (this context has source()):
{{ my_macro(source('jaffle_shop', 'orders')) }}
```

```sql
-- in macros/my_macro.sql (takes the resolved relation as an argument):
{% macro my_macro(orders_relation) %}
select * from {{ orders_relation }}
{% endmacro %}
```

Expected: the macro body contains no bare `source()` calls of its own.

### 4. Recompile the model

```bash
dbt compile --select stg_orders
```

Expected: `Done.` with no compilation error, and the compiled SQL under `target/compiled/[project]/models/staging/stg_orders.sql` contains the fully resolved table name (for example `raw.jaffle_shop.orders`).

## When to use this skill

- The error text is exactly `'source' is undefined` (a Jinja `UndefinedError`) naming the `source` function itself.
- `dbt compile`, `dbt run`, `dbt parse`, or `dbt docs` fails while rendering a model, a docs block, or a macro.

## When NOT to use this skill

- The error names a specific source, for example `Source 'jaffle_shop' not found` or `depends on a source named X which was not found`. That means `source()` ran fine but the name matches no `sources:` declaration: check `sources.yml` names instead.
- The undefined name is `ref`, `var`, or `config` rather than `source`. Same family of problem, different function.

## Variant phrasings

### Compilation Error: 'source' is undefined

dbt surfaces this as `Compilation Error in model [name] ([path])` followed by `'source' is undefined`. Same cause, same fix.

### dbt Jinja UndefinedError on source()

Any `jinja2.exceptions.UndefinedError: 'source' is undefined` traceback during `dbt parse`, `dbt compile`, or `dbt run` is this issue.

## Why it happens

dbt renders different files with different Jinja contexts. `source()` is a context function dbt injects when rendering models, tests, snapshots, and macros invoked from them. Documentation blocks (`{% docs %}`) are rendered with a docs-only context that provides just `doc()` plus base variables, so any `source()` call inside one is an undefined name to Jinja. The fix is structural: keep relation-resolving calls in the model SQL, keep docs as static text.

## Edge cases

- The traceback points at your model's `.sql` file directly and the call is in the body: look for a second file defining the same model name, or a `{% docs %}` block embedded in the `.sql` file itself. Also confirm the file sits under a parsed `model-paths` directory; a file dbt parses as something other than a model gets a different context.
- dbt Cloud and dbt CLI use the same rendering contexts, so the fix does not depend on where you run dbt.
- If you are on the dbt Fusion engine, malformed zero-argument `source()` calls now get a located error instead of a panic, but the docs-block scoping rule is unchanged.


## Matched thread
Source: Vectle search thread
Original query: ""dbt: 'source' is undefined in staging model""
Key terms: model, source, staging, undefined
