## TL;DR

The model calls `source('raw', 'orders')` but dbt has no such source declared. Define it in a `_sources.yml` file under your model paths with the right database, schema, and table, then recompile. The `source()` function only knows about declared sources.

## Error

```text
"dbt: 'source' is undefined in staging model"
```

## Steps

1. Find the `source()` call in the staging model and note both arguments: source name and table name. Expected: you know exactly what dbt is looking for.
2. Check for a `_sources.yml` (or `sources.yml`) file under your model paths that declares that source. Expected: you find it missing or misspelled.
3. Add or fix the declaration:
```yaml
version: 2
sources:
  - name: raw
    database: [YOUR DATABASE]
    schema: [YOUR SCHEMA]
    tables:
      - name: orders
```
Expected: the source name and table name match the `source()` call exactly.
4. Run `dbt ls --resource-type source --select source:raw.orders`. Expected: dbt lists the source.
5. Run `dbt compile --select [STAGING MODEL]`, then `dbt run --select [STAGING MODEL]`. Expected: the model builds.

## When to use

- A model fails with "'source' is undefined".
- You just added a new raw table reference to a staging model.

## When not to use

- The error is "'ref' is undefined" (a model-name problem, not a source problem).
- The source is declared but the table name is wrong (fix the table entry).

## Tool compatibility

- dbt Core 1.0 and later, all adapters. Source declarations are adapter-independent.

## Variant phrasings

### Source 'raw.orders' not found

The same problem phrased as a lookup failure; the declaration is still the fix.

### source() called with one argument

`source()` always takes two arguments (source name, table name); a single argument is a different error.

## Why it happens

Unlike `ref()`, which resolves against model files, `source()` resolves against declared source definitions. An undeclared source is invisible to dbt, so the function has nothing to resolve.

## Edge cases

- The `_sources.yml` file must live under a configured `model-paths` (or `source-paths`) directory, or dbt never parses it.
- Database and schema in the declaration must match the warehouse exactly, including case on Snowflake.
- Freshness checks also read these declarations; a bad declaration breaks `dbt source freshness` too.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_7plPJvPnEBNJjG4bqgrf5w
