dbt-labs/dbt-core · warning
InvalidConfig
InvalidConfig
Error message
Resource path `{key_path}` in dbt_project.yml starts with `+`. This will be deprecated in future versions of dbt. What it means
A deprecation warning from the dbt project-file parser: a resource-path key under a config section (models, seeds, snapshots, etc.) in dbt_project.yml starts with '+', and the sub-tree carries actual config values (value.has_set_fields() is true). The '+' prefix convention for configs in dbt_project.yml is being deprecated, so warn_plus_prefixed_resource_paths emits one warning at the topmost '+'-prefixed key of each offending resource path (code InvalidConfig). Parsing continues; the config still applies today.
Source
Thrown at crates/dbt-parser/src/dbt_project_config.rs:482
};
// Case 1: `value` is non-default, meaning there is a valid config inside it somewhere.
// We definitely know a config value was set, because it must have this shape:
//
// ```
// +key:
// +some_config: some_value
// ```
//
// This is just an approximation and will miss cases where the config is explicitly set to
// default.
let valid_config_exists = value.has_set_fields();
// We want to throw warnings at the location of the topmost +-prefixed key, so we throw exactly
// one warning per offending resource path.
let is_parent_plus = key_is_plus && !inside_plus;
if is_parent_plus && valid_config_exists {
warn();
return key_is_plus;
}
// Case 2: Any non-config children start with +, or any descendants fall under case 1.
let mut any_child_plus = false;
for (child_key, child_variant) in value.iter_children() {
let child_is_plus = match child_variant {
ShouldBe::AndIs(child) => warn_plus_prefixed_resource_paths::<S>(
child_key,
child,
&key_path,
inside_plus || key_is_plus,
),
ShouldBe::ButIsnt(..) => child_key.starts_with('+'),
};
any_child_plus |= child_is_plus;
}
if is_parent_plus && any_child_plus {View on GitHub (pinned to 0267ce9170)
Solutions
- Remove the '+' prefix from resource-path keys in dbt_project.yml: use 'my_model: materialized: table' style nested configs
- Keep '+' prefixes only where still required (e.g. seed/test config keys under subdirectories if applicable) and audit each section of dbt_project.yml
- Run dbt parse/dbt debug and clear each reported path until no warnings remain
Example fix
# before (dbt_project.yml)
models:
my_project:
+materialized: table
# after
models:
my_project:
config:
materialized: table Defensive patterns
Strategy: validation
Validate before calling
import yaml
def find_plus_keys(node, path=""):
if isinstance(node, dict):
for k, v in node.items():
p = f"{path}.{k}" if path else k
if k.startswith('+'):
print(f"Deprecated '+' prefix: {p}")
find_plus_keys(v, p) Prevention
- Lint dbt_project.yml in CI for '+'-prefixed keys under models/seeds/snapshots
- Migrate to explicit 'config:' blocks when upgrading dbt versions
- Read the dbt release notes for deprecation timelines of the '+' convention
When it happens
Trigger: dbt_project.yml contains e.g. 'models: { +my_model: { +materialized: table } }' or any '+'-prefixed resource key whose nested value sets at least one config field; triggered at the outermost plus key (inside_plus == false).
Common situations: Upgrading from dbt versions where '+key:' was the documented convention; mixed legacy/new configs after migration; linters or generators that still emit '+'-prefixed project configs.
Understand the failure class
Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.
Related errors
- Version '{:?}' does not meet the required format
- Contract Error for {} from {}: {}
- Contract Error: {message}
- config requires all arguments to be defined, but '{key}' is
- Failed to serialize merged node config to dbt_yaml::Value fo
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/340305eb100d39b9.
Report an issue: GitHub.