dbt-labs/dbt-core · error
Invalid config object specified
Error message
Invalid config object specified
What it means
When processing a `{{ config(...) }}` call at parse time, a positional argument is expected to be an iterable object of key/value pairs; `try_iter_pairs()` is unwrapped with `expect('Invalid config object specified')`. The panic fires when the positional config argument is an object that cannot be iterated as pairs (e.g. a non-dict object, or a scalar that slipped past the earlier object check).
Source
Thrown at crates/dbt-jinja-utils/src/phases/parse/resolve_model_context.rs:809
) -> Result<MinijinjaValue, MinijinjaError> {
let mut args = ArgParser::new(args, None);
// If there is a positional argument, it must be a map
let kwargs = if args.positional_len() == 1 {
let positional_val: MinijinjaValue = args.next_positional::<MinijinjaValue>()?;
if positional_val.kind() != ValueKind::Map {
return Err(MinijinjaError::new(
MinijinjaErrorKind::InvalidOperation,
format!(
"Invalid config argument kind specified: {}",
positional_val.kind()
),
));
}
positional_val
.as_object()
.unwrap()
.try_iter_pairs()
.expect("Invalid config object specified")
.map(|(k, v)| {
(
k.as_str()
.expect("Invalid config object specified. Keys must be strings")
.to_string(),
v,
)
})
.collect()
} else {
args.drain_kwargs()
};
self.apply_config(state, kwargs)
}
fn call_method(
self: &Arc<Self>,View on GitHub (pinned to 0267ce9170)
Solutions
- Ensure the positional argument to `{{ config(...) }}` is a plain dict with string keys, e.g. `{{ config(materialized='table') }}` or `{{ config({'materialized': 'table'}) }}`
- If a macro builds the config, have it return a normal dict (not a custom object)
- Log/print the value in the model to see its actual type before the config call
- At the code level, replace expect with an error message that includes the received value's type
Example fix
// before (model.sql)
{{ config(some_macro_that_returns_object()) }}
// after
{% set cfg = some_macro_that_returns_dict() %}
{{ config(cfg) }} Defensive patterns
Strategy: validation
Validate before calling
{% set cfg = my_config_arg() %}
{% if cfg is not mapping %}
{{ exceptions.raise_compiler_error("config() positional arg must be a dict, got: " ~ type(cfg)) }}
{% endif %}
{{ config(cfg) }} Type guard
// in jinja: only pass mappings
{% if cfg is mapping %}{{ config(cfg) }}{% endif %} Try / catch
// in Rust, replace expect with a descriptive error
obj.try_iter_pairs().ok_or_else(|| MinijinjaError::new(
ErrorKind::InvalidOperation, "config() positional arg must be an iterable dict"))?; Prevention
- Call config() with keyword args or plain dicts only
- Ensure macros building configs return plain dicts
- Use `is mapping` tests in jinja before passing values to config()
- Avoid passing lists/scalars positionally to config()
When it happens
Trigger: Calling `{{ config(some_object) }}` where the object is not a plain dict — e.g. a minijinja native object, a function, a struct-like value, or a nested/odd type returned by a macro that passes the `as_object()` check but not pair iteration.
Common situations: Macros returning custom objects into config(); passing a list or string positionally to config(); users passing `config(kwargs)` where kwargs was rebuilt into an unsupported type.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Invalid config object specified. Keys must be strings
- Failed to convert quoting to resolved quoting
- Failed to serialize merged node config to dbt_yaml::Value fo
- get_view_options: Failed to deserialize config: {e}
- get_common_options: Failed to deserialize config: {e}
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/44cebe5e879d6b4b.
Report an issue: GitHub.