How to Fix dbt Compilation Errors
Compilation errors occur when dbt cannot successfully parse your Jinja templates or YAML files. These errors typically appear before any SQL is executed.
Common Symptoms
- Missing dbt dependencies
- Jinja syntax errors
- Invalid macro references
- Malformed YAML
- Missing model references
Solution Steps
Install dbt packages
dbt deps
Check Jinja Syntax
Review your Jinja code for common issues:
-
Verify bracket closure: ```jinja {# Correct #} {{ ref('model_name') }}
{# Incorrect, missing ) #} {{ ref('model_name' }} {# Incorrect, missing } #} {{ ref('model_name') } {# Incorrect, missing { and } #} { ref('model_name') }
```
-
Check macro syntax: ```jinja {# Correct #}
{# Incorrect, missing } #} {% set my_var = 'value' % {# Incorrect, uses {{ }} instead of {% %} #} {{ set my_var = 'value' }}
```
Validate Model References
Ensure all referenced models and sources exist:
-
Check spelling of model names in
ref()
functions -
Check spelling of sources and tables in
source()
functions - Check name caseing. It is a best practice to name everything in lower case to avoid issues.
Review YAML Formatting
YAML files must follow strict formatting rules:
- Check indentation:
# Correct
version: 2
models:
- name: my_model
columns:
- name: id
data_tests:
- unique
- not_null
- accepted_values:
values: ['placed', 'shipped', 'completed', 'returned']
# Incorrect indentation
models:
- name: my_model
columns:
- name: id
data_tests:
- unique
- not_null
- accepted_values:
values: ['placed', 'shipped', 'completed', 'returned']
```
A good way to think of indentation is "Is the property I am adding a sub-set of the prior item?". This is why the `name:` of each model is indented below models.
The same is true for columns and tests. Notice that `values:` is indented below `accepted_values:` because those are properties of that specific test.
2. Verify list formatting
When you have a list of items, they start with `-`. That is why `name` in both models and columns start with `-` because each is a list of models or columns respectively. The same can be see in `data_tests:` because there can be more than one test.
3. Check for special character handling
Check that you don't have strange characters in the yml file. This can happen if you copy/paste text from another source such as an MS Word file.
If you have a long description, you can also make it a multi line string using `>-`. Note: adding the `-` is preferable because without it, the docs would compile with an extra new line at the end of the text block.
```yaml
tables:
- name: us_population
description: >-
This source represents the raw data table containing information about the population of the
United States.
Common Error Messages
Error Message | Likely Cause | Solution |
---|---|---|
Parsing Error
|
Invalid YAML formatting issue | Check indentation and structure |
Compilation Error
|
Invalid reference | Verify model exists and is spelled correctly |
Compilation Error unknown tag
|
Jinja syntax issue | Check syntax |
Best Practices
- Use a YAML validator for complex configurations
- Break down complex Jinja logic into smaller macros
- Maintain consistent indentation
- Document custom macros clearly
Model Attribute Debugging
{# Debug specific model #}
{% macro output_model_info(model_name) %}
{% for model in graph.nodes.values() %}
{% if model.name == model_name %}
{# Print all available keys to see what we can access #}
{{ print('=' * 50) }}
{{ print('AVAILABLE MODEL PROPERTIES:') }}
{{ print('-' * 30) }}
{% for key in model.keys() %}
{{ print('- ' ~ key) }}
{% endfor %}
{{ print('=' * 50) }}
{{ print('MODEL: ' ~ model.name) }}
{{ print('FILE PATH: ' ~ model.original_file_path) }}
{{ print('Relation: ' ~ model.relation_name) }}
{{ print('=' * 50) }}
{{ print('BASIC INFORMATION:') }}
{{ print('-' * 30) }}
{{ print('Package: ' ~ model.package_name) }}
{{ print('Path: ' ~ model.path) }}
{{ print('Original File Path: ' ~ model.original_file_path) }}
{{ print('Resource Type: ' ~ model.resource_type) }}
{{ print('Unique ID: ' ~ model.unique_id) }}
{{ print('\nCONFIGURATION:') }}
{{ print('-' * 30) }}
{{ print('Materialization: ' ~ model.config.materialized) }}
{{ print('Depends On:') }}
{% for depend in model.depends_on.nodes %}
{{ print(' - ' ~ depend) }}
{% endfor %}
{% endif %}
{% endfor %}
{%- endmacro %}
You can run this from the terminal as follows.
dbt run-operation output_model_info --args '{model_name: us_population}'
Next Steps
If errors persist:
- Review the dbt documentation for proper syntax
- Use a YAML linter for configuration files
- Break down complex templates into smaller parts
- Consider using dbt package templates as examples