dbt Tests Failing with Iceberg Version Error - Investigation Report
Date: December 7, 2025
Status: π΄ Issue Identified - Awaiting Fix Approval
Executive Summary
Section titled βExecutive SummaryβThe dbt models are now building successfully (PASS=10), but 17 tests are failing with the Iceberg version guessing error. This is because dbt tests donβt inherit model-level pre-hooks.
Key Insight: Pre-hooks only run when creating models, not when running tests. Tests execute as separate SQL statements in their own sessions.
Error Analysis
Section titled βError AnalysisβSummary Statistics
Section titled βSummary StatisticsβDone. PASS=10 WARN=0 ERROR=17 SKIP=13 NO-OP=0 TOTAL=40Whatβs Passing β
Section titled βWhatβs Passing β β- Bronze models: raw_products, raw_customers, raw_cross_references, raw_shipping_addresses, raw_ship_to_links (5 models)
- Silver models: stg_products, stg_customers, stg_cross_references, stg_shipping_addresses (4 models)
- Gold models: dim_products (1 model)
Whatβs Failing β
Section titled βWhatβs Failing ββIssue 1: 16 Tests Failing with Iceberg Version Error
Section titled βIssue 1: 16 Tests Failing with Iceberg Version ErrorβAll column-level tests are failing with the same error:
Runtime Error in test not_null_stg_products_connection_id (models/silver/schema.yml)Failed to read iceberg table. No version was provided and no version-hint could be found,globbing the filesystem to locate the latest version is disabled by default as this isconsidered unsafe and could result in reading uncommitted data.To enable this use 'SET unsafe_enable_version_guessing = true;'Affected Tests:
| Layer | Test | Status |
|---|---|---|
| Silver | not_null_stg_products_connection_id |
β ERROR |
| Silver | not_null_stg_products_erp_product_id |
β ERROR |
| Silver | not_null_stg_products_name |
β ERROR |
| Silver | accepted_values_stg_products_active__True__False |
β ERROR |
| Silver | accepted_values_stg_products_delete_flag__True__False |
β ERROR |
| Silver | not_null_stg_customers_connection_id |
β ERROR |
| Silver | not_null_stg_customers_erp_customer_id |
β ERROR |
| Silver | not_null_stg_customers_name |
β ERROR |
| Silver | accepted_values_stg_customers_delete_flag__True__False |
β ERROR |
| Silver | not_null_stg_cross_references_connection_id |
β ERROR |
| Silver | not_null_stg_cross_references_customer_id |
β ERROR |
| Silver | not_null_stg_cross_references_item_id |
β ERROR |
| Silver | not_null_stg_cross_references_their_item_id |
β ERROR |
| Silver | not_null_stg_shipping_addresses_connection_id |
β ERROR |
| Silver | not_null_stg_shipping_addresses_erp_shipping_id |
β ERROR |
| Silver | not_null_stg_shipping_addresses_customer_id |
β ERROR |
Issue 2: 1 Test Failing with SQL Syntax Error
Section titled βIssue 2: 1 Test Failing with SQL Syntax ErrorβRuntime Error in test dbt_utils_expression_is_true_stg_products_list_price__list_price_0 (models/silver/schema.yml)Parser Error: syntax error at or near "list_price"Location: models/silver/schema.yml, line 37-38
- name: list_price description: 'List price (should be non-negative)' tests: - dbt_utils.expression_is_true: expression: 'list_price >= 0'Root Cause: The expression_is_true test generates SQL that DuckDB canβt parse. This might be a compatibility issue with dbt_utils and DuckDB, or the expression syntax needs adjustment.
Root Cause Analysis
Section titled βRoot Cause AnalysisβWhy Tests Fail While Models Pass
Section titled βWhy Tests Fail While Models Passββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ dbt Build Process βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€β ββ 1. Model Creation (with pre-hooks) ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ β -- Pre-hook runs first (model session) β ββ β SET unsafe_enable_version_guessing = true; β ββ β β ββ β -- Then model SQL executes β ββ β CREATE VIEW stg_products AS SELECT * FROM... β ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ β
SUCCESS - Pre-hook setting is active ββ ββ 2. Test Execution (separate session, NO pre-hooks) ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ β -- Test SQL executes directly (NEW session) β ββ β SELECT * FROM stg_products WHERE connection_id IS...β ββ β β ββ β -- stg_products is a VIEW that references β ββ β -- raw_products which uses iceberg_scan() β ββ β -- But unsafe_enable_version_guessing is NOT set! β ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββ β FAIL - Session doesn't have the setting ββ βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββKey Insight
Section titled βKey Insightβdbtβs +pre-hook configuration only applies to model materialization, not to test execution. Tests run as separate SQL queries in fresh DuckDB sessions without the pre-hook settings.
Solution Options
Section titled βSolution OptionsβOption A: Use on-run-start Hook (RECOMMENDED)
Section titled βOption A: Use on-run-start Hook (RECOMMENDED)βApproach: Use a project-level hook that runs once at the start of every dbt run, applying to ALL operations including tests.
Implementation:
on-run-start: - 'INSTALL httpfs; LOAD httpfs;' - 'INSTALL iceberg; LOAD iceberg;' - 'SET unsafe_enable_version_guessing = true;'Pros:
- β Applies to all models AND tests
- β Single location for configuration
- β Runs once per dbt invocation (efficient)
Cons:
- β οΈ Global setting for entire dbt run
Option B: Enable in profiles.yml Globally
Section titled βOption B: Enable in profiles.yml GloballyβApproach: Set unsafe_enable_version_guessing: true in profiles.yml settings.
Implementation:
erp_pipeline: target: dev outputs: dev: type: duckdb path: ':memory:' settings: unsafe_enable_version_guessing: true # β Already here but set to falsePros:
- β Simplest change (one line)
- β Applies to everything
Cons:
- β οΈ We previously set this to
falseintentionally - β οΈ Comment says βOnly enable for controlled testingβ
Option C: Disable Tests Temporarily
Section titled βOption C: Disable Tests TemporarilyβApproach: Skip tests in the dbt build command.
Implementation:
dbt build --exclude-testsPros:
- β Immediate unblock
Cons:
- β Loses data quality checks
- β Not a real fix
Additional Issue: SQL Syntax Error in expression_is_true Test
Section titled βAdditional Issue: SQL Syntax Error in expression_is_true TestβParser Error: syntax error at or near "list_price"Location
Section titled βLocationβ- name: list_price tests: - dbt_utils.expression_is_true: expression: 'list_price >= 0'Possible Causes
Section titled βPossible Causesβ- dbt_utils incompatibility with DuckDB: The macro might generate SQL that DuckDB canβt parse
- Expression syntax issue: The expression might need different quoting or syntax
- Column reference issue: May need to use the full model reference
Recommended Action
Section titled βRecommended ActionβTemporarily disable this test until we can investigate the syntax issue:
# Comment out or remove temporarily# - dbt_utils.expression_is_true:# expression: 'list_price >= 0'Recommendation
Section titled βRecommendationβImmediate Fix: Option A (on-run-start hook)
Section titled βImmediate Fix: Option A (on-run-start hook)βRationale:
- Applies to both models AND tests
- Centralizes configuration in one place
- More appropriate than model-level pre-hooks for global settings
- Already proven safe in our controlled environment
Implementation
Section titled βImplementationβ# dbt_project.yml - Add at top level (not under models:)
on-run-start: - 'INSTALL httpfs; LOAD httpfs;' - 'INSTALL iceberg; LOAD iceberg;' - 'SET unsafe_enable_version_guessing = true;'
models: erp_pipeline: bronze: +materialized: view +tags: - bronze # Remove pre-hooks from here (moved to on-run-start) silver: +materialized: view +tags: - silver gold: +materialized: view +tags: - goldSecondary Fix: Disable Problematic Test
Section titled βSecondary Fix: Disable Problematic TestβComment out the expression_is_true test for list_price until we can investigate the DuckDB compatibility issue:
- name: list_price description: 'List price (should be non-negative)' # tests: # - dbt_utils.expression_is_true: # expression: 'list_price >= 0'Files to Modify
Section titled βFiles to Modifyβapps/dagster/dbt/dbt_project.yml- Addon-run-starthook, optionally remove model pre-hooksapps/dagster/dbt/models/silver/schema.yml- Disable problematicexpression_is_truetest
References
Section titled βReferencesβ- dbt Hooks Documentation
- Previous research:
debt/bug-report-analysis/iceberg-version-handling-research-2025-12-07.md