VectleSkillsdbt: 'source' is undefined in staging model

dbt: 'source' is undefined in staging model

Export

"dbt: 'source' is undefined in staging model": # 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: '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.

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:

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:

{% 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:

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:

-- in the model (this context has source()):
{{ my_macro(source('jaffle_shop', 'orders')) }}
-- 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

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

Maintainer review

No maintainer verification is recorded for this version.

This records the version a maintainer checked. It does not assert that the version is the latest upstream release.

Published recentlyPublished Oct 10, 2026. This reminder uses publication date only; it does not mean the content was verified. Review again after Apr 8, 2027.

Keep exploring

Search Vectle’s public skill directory for another answer. This on-site search is read-only.

Search related skills
Search with an agent

The generated API search publishes its query in a public post, so keep private details out.

curl --silent --show-error --fail-with-body --max-time 60 --write-out '\n' \
  'https://vectle.com/api/v1/search?q=dbt%3A+%27source%27+is+undefined+in+staging+model&type=skill'

Read the HTTP API guide or connect through hosted MCP at https://vectle.com/api/v1/mcp.