В этом уроке — каталог ошибок, с которыми junior-аналитик столкнётся в первые две недели работы с dbt. По каждой — типичный текст из лога, причина и фикс в 3 шага. Этот урок построен как справочник: открывай его, когда увидишь похожую ошибку.
Распределение по моему наблюдению за 50+ stand-up'ами начинающих. Compilation/Database — половина всех проблем.
1. Compilation Error: Model X depends on a node named Y which was not found
Текст:
Compilation Error in model customers (models/marts/customers.sql)
Model 'customers' (models/marts/customers.sql) depends on a node named 'stg_jaffle__orders' which was not found
Причина: В customers.sql есть {{ ref('stg_jaffle__orders') }}, но модель с таким именем в проекте отсутствует.
Фикс в 3 шага:
- Проверь имя модели — открой
models/staging/и найди файл. Может быть опечатка:stg_jaffle__orders.sqlvsstg_jaffle_orders.sql(одна или две_). - Проверь
dbt list --resource-type model | grep stg_jaffle— есть ли вообще такая модель в зрении dbt. Если нет — возможно, файл лежит внеmodel-paths(по умолчанию['models']). - Если модель есть, но не «видится» —
dbt clean && dbt parse. Возможно, partial-parse кеш протух.
2. Database Error: Table X does not exist
Текст:
Database Error in model orders (models/marts/orders.sql)
Catalog Error: Table "stg_orders" does not exist!
Did you mean "main.stg_orders"?
Причина: dbt пытается выполнить select ... from stg_orders ..., но таблицы stg_orders в текущей схеме нет. Чаще всего — в SQL прямое имя таблицы вместо {{ ref() }}, или upstream модель не материализована.
Фикс в 3 шага:
- Открой
target/compiled/jaffle_shop/models/marts/orders.sql. Найди FROM-секцию. Если видишь голоеstg_orders(без префикса схемы и без кавычек) — в исходнике hardcoded имя, замени на{{ ref('stg_orders') }}. - Если в compiled SQL правильное
"jaffle_shop"."main"."stg_orders"— это значит, таблицы реально нет в БД. Запустиdbt run --select stg_ordersилиdbt run --select +orders(соберёт всё upstream). - Альтернатива: в DuckDB-shell выполни
.tables(илиSHOW TABLES;) и убедись, что таблица существует.
3. Compilation Error: Source X.Y not found
Текст:
Compilation Error in model stg_orders (models/staging/stg_orders.sql)
Source 'raw_jaffle.orders' was not found
Причина: В модели {{ source('raw_jaffle', 'orders') }}, но source raw_jaffle (или таблица orders в нём) не объявлен в каком-то _sources.yml.
Фикс в 3 шага:
- Открой
models/staging/_sources.yml(или другой YAML с sources). Проверь:sources: - name: raw_jaffle tables: - name: orders - Если source есть, но таблицы нет — добавь
- name: ordersвtables. - Если опечатался в имени source: исправь либо в YAML, либо в модели. Проверь
dbt list --resource-type source— какие dbt видит.
4. Compilation Error: Macro X is undefined
Текст:
Compilation Error in model customers
'dbt_utils.star' is undefined
Причина: Макрос из пакета (например, dbt_utils), но пакет физически не подтянут — dbt_packages/ пуста.
Фикс в 3 шага:
- Проверь
packages.yml— есть ли там dbt_utils:packages: - package: dbt-labs/dbt_utils version: 1.3.0 - Запусти
dbt deps. Должно вывестиInstalled dbt-labs/dbt_utils. - Если макрос свой (не из пакета): проверь, что файл
macros/<name>.sqlсуществует иmacro-pathsвdbt_project.ymlуказывает на['macros'](по умолчанию).
5. Connection Error: Could not connect to database
Текст:
Connection 'master' to duckdb at path './jaffle_shop.duckdb' failed
Permission denied
Причина: Несколько вариантов:
- DuckDB-файл заблокирован другим процессом (single-writer)
- Неправильный путь (относительный путь от текущей директории, не от проекта)
- Профиль в
profiles.ymlимеет неправильный формат
Фикс в 3 шага:
dbt debug— посмотри, на каком именно блоке падает. Еслиprofiles.yml file [ERROR]— проблема в YAML. ЕслиConnection test: [ERROR]— проблема в самом подключении.- Закрой все открытые SQL-клиенты (DBeaver, DataGrip, duckdb shell) — DuckDB single-writer per file.
- Проверь путь в
profiles.yml. Стандартно:path: './jaffle_shop.duckdb'— относительноdbt_project.yml. Если путь начинается с/, это абсолютный.
6. Source Freshness Error: STALE
Текст:
ERROR STALE freshness of jaffle.orders ............................. [ERROR STALE in 0.04s]
Source 'jaffle.orders' is stale. Loaded 26 hours ago, max_loaded_at: 2026-05-18T14:23:00Z
error_after: {count: 24, period: hour}
Причина: В sources.yml настроено freshness: error_after: {count: 24, period: hour}. dbt посчитал now() - max(loaded_at_field) и получил >24 часов. Источник «протух».
Фикс в 3 шага:
- Проверь, что ingestion-пайплайн (Airbyte / Fivetran / Stitch / самописный) работает. Если он упал — фиксить там, не в dbt.
- Если freshness нужно временно отключить (например, разработка идёт на старом снэпшоте): закомментировать
freshness:блок в YAML. - Если этот источник вообще не должен быть «свежим» (исторические дамп): убрать
freshness:совсем или поменятьerrorнаwarn.
7. YAML Parsing Error: mapping values are not allowed here
Текст:
Compilation Error
mapping values are not allowed here at line 8, column 12 in models/staging/_models.yml
Причина: YAML битый. Обычно:
- табы вместо пробелов (YAML не разрешает табы для отступов)
- незакрытая строка с кавычками
- неправильный отступ (особенно в nested-структурах)
Фикс в 3 шага:
- Открой указанный файл, перейди на указанную строку и столбец.
- Используй YAML-валидатор — VS Code расширение или онлайн (yamlchecker.com). Покажет точную проблему.
- Самый частый случай — отступ. Открой соседнюю валидную секцию и сравни количество пробелов перед
-илиname:.
В YAML отступ всегда пробелами, не табами. Многие редакторы по умолчанию вставляют табы. Включи View / Render Whitespace чтобы видеть символы.
8. Test Failure: Got N results, configured to fail if != 0
Текст:
Failure in test not_null_customers_customer_id (models/marts/_models.yml)
Got 3 results, configured to fail if != 0
compiled Code at target/compiled/jaffle_shop/models/marts/_models.yml/not_null_customers_customer_id.sql
Причина: Тест not_null нашёл 3 строки с NULL в customer_id. Это твоя ответственность — либо данные грязные, либо тест неуместный.
Фикс в 3 шага:
- Открой
target/compiled/.../not_null_customers_customer_id.sql. Это SELECT, который вернул 3 строки. Скопируй в SQL-клиент, посмотри, какие именно строки нарушают. - Если NULL — баг в upstream (например, LEFT JOIN без COALESCE). Исправь модель.
- Если NULL легитимный (например, ещё не зарегистрированные клиенты): добавь WHERE-фильтр в модель, или поменяй тест на
not_null->not_nullсwhere:параметром:data_tests: - not_null: where: "registered = true"
Или поставь severity: warn чтобы не блокировать downstream.
Дополнительные паттерны (бонус)
Database Error: out of memory
В DuckDB. Тяжёлая агрегация не помещается:
Out of Memory Error: failed to allocate 2147483648 bytes
Фикс: в profiles.yml:
jaffle_shop:
outputs:
dev:
type: duckdb
path: './jaffle_shop.duckdb'
settings:
memory_limit: '8GB'
temp_directory: '/tmp/duckdb_spill'
temp_directory важен — позволяет DuckDB сбрасывать промежуточные данные на диск.
Compilation Error: parser found unexpected token
Битый SQL-синтаксис где-то в модели. Часто — забытая запятая после колонки или незакрытая скобка.
Фикс: dbt compile --select <model>, открой compiled SQL, проверь синтаксис. Можно прогнать через линтер sqlfluff.
Compilation Error: invalid Jinja syntax
unexpected '%}' at line 5
В Jinja не закрыта/некорректна {% ... %}. Чаще всего — забытый {% endfor %} или {% endif %}.
Фикс: счёт {% ... %} — для каждого {% for %} должен быть {% endfor %}, для {% if %} — {% endif %}.
is_incremental() but no destination table
Database Error: column "max_id" does not exist
В инкрементальной модели первый раз. is_incremental() возвращает false при первом запуске (таблицы ещё нет), но логика модели должна это учитывать через {% if is_incremental() %} блок.
Фикс:
{{ config(materialized='incremental', unique_key='order_id') }}
select * from {{ ref('stg_orders') }}
{% if is_incremental() %}
where updated_at > (select max(updated_at) from {{ this }})
{% endif %}
Без {% if is_incremental() %} модель попытается обратиться к {{ this }} на первой пересборке, и таблицы ещё нет.
Run failure, но Postgres-у нравится: relation does not exist
В Postgres-warehouse: dbt пишет в dev_<имя_юзера>_<схема>, ты в SQL-клиенте смотришь <схема>. Это generate_schema_name magic — не баг, фича.
Фикс: прочитай модуль 14 про project structure и schema-name customization. На dev-target обычно делают модели в dev_<user>_<schema>, чтобы коллеги не пересекались.
Универсальный алгоритм при любой ошибке
1. Прочитай терминальный вывод. Это краткая выдержка.
2. dbt debug — проверь окружение.
3. Открой logs/dbt.log, ищи ERROR. Скролл вверх до SQL-statement.
4. Открой target/compiled/<model>.sql — посмотри финальный SQL.
5. Скопируй SQL в SQL-клиент, прогоны вручную. Получишь точную ошибку.
6. Гугл уже опционально.
Гугл — последний шаг, не первый. 90% ошибок junior фиксятся открытием правильного файла в target/ и парой минут чтения compiled SQL.
Попробуй сам
Создай по очереди каждую из 8 ошибок и почини. Пройди алгоритм debug -> compile -> logs:
-
Compilation Error not found: в
customers.sqlнапиши{{ ref('stg_doesnt_exist') }}. Запустиdbt run --select customers. Прочитай ошибку. Исправь. -
Database Error: в
customers.sqlзамени{{ ref('stg_jaffle__orders') }}на простоstg_jaffle__orders. Запусти. Прочитай. Исправь. -
Macro undefined: удали
dbt_utilsизpackages.yml, не запускаяdbt deps. Запусти модель, использующуюdbt_utils.star. Прочитай. Восстанови. -
YAML parsing: добавь таб вместо двух пробелов где-то в
_models.yml. Запустиdbt compile. Прочитай. Исправь. -
Test failure: создай
not_nullтест на колонке, где есть NULL. Запустиdbt test. Прочитай вывод. Открой compiled test SQL, посмотри строки.
Чек-лист
- 8 типичных ошибок покрывают 90% случаев junior.
- Каждая ошибка имеет 3-шаговый рецепт.
- Универсальный workflow: terminal -> debug -> logs -> compiled SQL -> SQL-клиент.
- compilation errors — про Jinja и структуру проекта.
- database errors — про SQL и состояние warehouse.
- macro undefined — почти всегда
dbt depsзабыли. - YAML parsing — отступы и табы, открыть в редакторе с whitespace.
- Test failure — открыть compiled test SQL, посмотреть проваленные строки.
- В DuckDB OOM — настроить
memory_limitиtemp_directory.