dbt-labs/dbt-core · info

root overlay config builds

Error message

root overlay config builds

What it means

A test-only `.expect()` in the project-config overlay test loop: after `init_project_config_from_yaml::<ModelConfig, ProjectModelConfig>` reports no errors, the root overlay config must exist (`Some`). A None here means the parser produced no errors but silently failed to build the root overlay, which the test treats as an internal bug.

Solutions

  1. Verify the fixture YAML actually produces a root overlay (non-empty `config:`/`models:` sections)
  2. Check for regressions in `init_project_config` after refactors and restore overlay construction
  3. Improve the assert to print the label and errors for diagnosis
  4. Run only the failing case and compare against a known-good fixture

Example fix

// before
let root = root.expect("root overlay config builds");

// after
let root = root.unwrap_or_else(|| panic!("{label}: root overlay config did not build"));
Defensive patterns

Strategy: validation

Validate before calling

assert!(errors.is_empty(), "{label}: {errors:?}");
let root = root.unwrap_or_else(|| panic!("{label}: root overlay missing"));

Prevention

When it happens

Trigger: Running the overlay resolution test where the fixture YAML parses without reported errors yet `init_project_config_from_yaml` returns None for the root config — usually caused by a change in config init behavior or a fixture the parser accepts but doesn't materialize into an overlay.

Common situations: Hit by developers changing `init_project_config` semantics or adding fixture cases whose YAML yields an empty/default root unexpectedly.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07). Data as JSON: /api/errors/2271ee2fa9ce39fd. Report an issue: GitHub.

Appendix: source

Thrown at crates/dbt-parser/src/dbt_project_config.rs:1745

            ("inherited from package", "pkg:\n  +enabled: true\n", true),
            ("global", "+enabled: true\n", true),
            (
                "absent",
                "pkg:\n  my_model:\n    +materialized: view\n",
                false,
            ),
            (
                "explicitly disabled",
                "pkg:\n  my_model:\n    +enabled: false\n",
                false,
            ),
        ];

        for (label, yml, expected) in cases {
            let (root, errors, _) =
                init_project_config_from_yaml::<ModelConfig, ProjectModelConfig>(yml, true);
            assert!(errors.is_empty(), "{label}: {errors:?}");
            let root = root.expect("root overlay config builds");
            let local = DbtProjectConfig::<ModelConfig> {
                config: ModelConfig::default(),
                children: IndexMap::new(),
            };
            let resolver =
                ProjectConfigResolver::for_dependency(local, root.clone(), AdapterType::Snowflake);
            assert_eq!(
                resolver.is_enabled_by_root_overlay(&fqn),
                expected,
                "{label}"
            );

            // Root packages have no overlay, so their own inline disable keeps winning.
            let root_resolver = ProjectConfigResolver::for_root(root, AdapterType::Snowflake);
            assert!(
                !root_resolver.is_enabled_by_root_overlay(&fqn),
                "{label}: root package must never be force-enabled"
            );

View on GitHub (pinned to 0267ce9170)