dbt-labs/dbt-core · error · minijinja::Error::SerdeDeserializeError
get_common_options: Failed to deserialize config: {e}
Error message
get_common_options: Failed to deserialize config: {e} What it means
get_common_options() converts its `config` argument into a ModelConfig struct via serde before computing shared DDL options. When the supplied config Value cannot be deserialized into ModelConfig, this SerdeDeserializeError is raised with the serde detail appended. It signals the config object passed from Jinja does not match the ModelConfig schema.
Source
Thrown at crates/dbt-adapter/src/adapter/mod.rs:2186
#[tracing::instrument(skip(self, state), level = "trace")]
pub fn get_common_options(
&self,
state: &State,
args: &[Value],
) -> Result<Value, minijinja::Error> {
match &self.inner {
Typed { adapter, .. } => {
let iter = ArgsIter::new("get_common_options", &["config", "node"], args);
let config_val = iter.next_arg::<&Value>()?;
let node_val = iter.next_arg::<&Value>()?;
let temporary = iter
.next_kwarg::<Option<bool>>("temporary")?
.unwrap_or(false);
iter.finish()?;
let config = minijinja_value_to_typed_struct::<ModelConfig>(config_val.clone())
.map_err(|e| {
minijinja::Error::new(
minijinja::ErrorKind::SerdeDeserializeError,
format!("get_common_options: Failed to deserialize config: {e}"),
)
})?;
let node = minijinja_value_to_typed_struct::<InternalDbtNodeWrapper>(
node_val.clone(),
)
.map_err(|e| {
minijinja::Error::new(
minijinja::ErrorKind::SerdeDeserializeError,
format!(
"get_common_options: Failed to deserialize InternalDbtNodeWrapper: {e}"
),
)
})?;
let options = adapter.get_common_options(state, config, &node, temporary)?;
Ok(options)View on GitHub (pinned to 0267ce9170)
Solutions
- Read the serde detail appended to the message to find the failing field.
- Pass config.model from the materialization context instead of a hand-built dict.
- Fix the offending value's type in the model config block or dbt_project.yml.
- Reconcile custom macros with this adapter version's ModelConfig field names and types.
Example fix
// before
{% do adapter.get_common_options({'temporary': 'true'}, model) %}
// after
{% do adapter.get_common_options(config.model, model, temporary=true) %} Defensive patterns
Strategy: validation
Validate before calling
{% if config.model is mapping %}
{% set opts = adapter.get_common_options(config.model, model, temporary=Temporary) %}
{% endif %} Prevention
- Pass config.model from the materialization context
- Validate config value types in YAML (booleans as booleans, tags as lists)
- Avoid renaming config keys consumed by ModelConfig
- Keep custom materializations updated against ModelConfig
When it happens
Trigger: adapter.get_common_options(config, node, temporary=...) called with a config dict containing fields of wrong types (e.g. non-bool where bool expected, non-list tags), unknown incompatible values, or a non-object config.
Common situations: Custom materializations (table/view/incremental) passing raw dicts instead of config.model; config keys renamed between dbt versions; user YAML values that fail strict typed parsing (e.g. a quoted boolean string).
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- get_view_options: Failed to deserialize config: {e}
- compute_external_path: Failed to deserialize config: {e}
- get_table_options: Failed to deserialize config: {e}
- get_table_options: Failed to deserialize InternalDbtNodeWrap
- get_view_options: Failed to deserialize InternalDbtNodeWrapp
AI-assisted analysis of dbt-labs/dbt-core@0267ce9170 (2026-09-07).
Data as JSON: /api/errors/c83ebb3571f02b46.
Report an issue: GitHub.