ServicesAboutNotesContact Get in touch →
EN FR
Note

Elementary materialization override for dbt 1.8+

Why Elementary requires a materialization override macro in dbt 1.8+ projects, what happens without it, and how to write it correctly for BigQuery and Snowflake.

Planted
dbtelementarydata qualitytesting

On dbt 1.8+, Elementary requires a materialization override macro in the consuming project. Without it, tests run without errors but elementary_test_results stays empty — a silent failure that is not surfaced by the dbt or Elementary output.

What changed in dbt 1.8

Before dbt 1.8, packages could freely override built-in materializations like test. Elementary used this to intercept each test execution and capture the result into its metadata tables.

dbt 1.8 tightened these rules. Packages can no longer override built-in materializations unless the consuming project explicitly allows it. The flag for this is require_explicit_package_overrides_for_builtin_materializations. Elementary’s docs tell you to set it to False, which re-enables the override behavior.

But setting the flag alone isn’t sufficient. You also need to declare the override in your own project’s macros directory. dbt 1.8’s model is that the project (not the package) controls which overrides are active. If you don’t write the macro in your project, Elementary’s override doesn’t activate, even with the flag set.

The two required pieces

In dbt_project.yml:

flags:
require_explicit_package_overrides_for_builtin_materializations: False
source_freshness_run_project_hooks: True

The second flag (source_freshness_run_project_hooks) ensures that on-run-end hooks fire after dbt source freshness commands, not just after dbt run and dbt test. Without it, freshness checks don’t populate Elementary’s tables.

Then create macros/elementary_materialization.sql in your project:

-- For BigQuery and most other adapters
{% materialization test, default %}
{{ return(elementary.materialization_test_default()) }}
{% endmaterialization %}

For Snowflake, use the adapter-specific version instead:

{% materialization test, adapter='snowflake' %}
{{ return(elementary.materialization_test_snowflake()) }}
{% endmaterialization %}

Do not use both versions in the same file. Pick the one that matches your warehouse.

Why the silent failure matters

The failure mode without this macro is genuinely hard to diagnose. Running dbt test succeeds. The Elementary package is installed. The elementary schema exists in your warehouse with all the right tables. But when you run edr report, you see no test results, or you see results from only the dbt run step and nothing from tests.

The tell is checking elementary_test_results directly:

SELECT COUNT(*) FROM your_schema_elementary.elementary_test_results

If that returns zero after running dbt test, the materialization override is almost certainly the issue.

The fix sequence once you’ve added the macro:

Terminal window
dbt deps
dbt run --select elementary --full-refresh
dbt test

The --full-refresh ensures Elementary’s tables are recreated cleanly. Then run tests to repopulate results and verify the count in elementary_test_results is now non-zero.

Checking your work

After adding the macro and running through the sequence, you should see rows in elementary_test_results for every test that ran. Each row captures the test name, model, result status, execution time, and the invocation ID. If you’re seeing rows, the override is working.

The Elementary setup troubleshooting note covers other failure modes and their fixes.