{"record":{"id":"778fba41e18c0bb5","repo":"dbt-labs/dbt-core","slug":"get-view-options-failed-to-deserialize-config-e","errorCode":null,"errorMessage":"get_view_options: Failed to deserialize config: {e}","messagePattern":"get_view_options: Failed to deserialize config: (.+?)","errorType":"exception","errorClass":"minijinja::Error::SerdeDeserializeError","httpStatus":null,"severity":"error","filePath":"crates/dbt-adapter/src/adapter/mod.rs","lineNumber":2143,"sourceCode":"        }\n    }\n\n    #[tracing::instrument(skip(self, state), level = \"trace\")]\n    pub fn get_view_options(\n        &self,\n        state: &State,\n        args: &[Value],\n    ) -> Result<Value, minijinja::Error> {\n        match &self.inner {\n            Typed { adapter, .. } => {\n                let iter = ArgsIter::new(\"get_view_options\", &[\"config\", \"node\"], args);\n                let config_val = iter.next_arg::<&Value>()?;\n                let node_val = iter.next_arg::<&Value>()?;\n                iter.finish()?;\n\n                let config = minijinja_value_to_typed_struct::<ModelConfig>(config_val.clone())\n                    .map_err(|e| {\n                        minijinja::Error::new(\n                            minijinja::ErrorKind::SerdeDeserializeError,\n                            format!(\"get_view_options: Failed to deserialize config: {e}\"),\n                        )\n                    })?;\n                let node = minijinja_value_to_typed_struct::<InternalDbtNodeWrapper>(\n                    node_val.clone(),\n                )\n                .map_err(|e| {\n                    minijinja::Error::new(\n                        minijinja::ErrorKind::SerdeDeserializeError,\n                        format!(\n                            \"get_view_options: Failed to deserialize InternalDbtNodeWrapper: {e}\"\n                        ),\n                    )\n                })?;\n\n                let inner_node = node.as_internal_node();\n                let options = adapter.get_view_options(state, config, inner_node.common())?;","sourceCodeStart":2125,"sourceCodeEnd":2161,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-adapter/src/adapter/mod.rs#L2125-L2161","documentation":"get_view_options() converts its `config` argument from a minijinja Value into a ModelConfig struct via serde. If the Value does not conform to ModelConfig (unexpected field types, invalid enum values, wrong nesting), deserialization fails and this SerdeDeserializeError is raised naming get_view_options and the serde detail. It means the config object handed to the macro is not a valid ModelConfig.","triggerScenarios":"Calling adapter.get_view_options(config, node) where config is a plain dict with fields that do not map to ModelConfig (e.g. materialization string not a known variant, wrong types for fields like tags or on_schema_change), or config is a non-object value.","commonSituations":"Custom view materializations passing config.model but ModelConfig schema expecting different field names/types; typos in config keys; version drift between the YAML/config schema and the Rust ModelConfig struct.","solutions":["Read the serde detail after the message to identify the offending config field.","Pass `config.model` (the model's config object) rather than arbitrary dicts.","Correct the type/value of the reported field in the model's config block (e.g. fix materialized, tags, or contract values).","Align custom macro code with the ModelConfig struct fields expected by this adapter version.","If a new config key is needed, it must be added to ModelConfig or be tolerated (unknown fields ignored) — check struct attributes."],"exampleFix":"// before\n{% do adapter.get_view_options({'materalized': 'view'}, model) %}\n\n// after\n{% do adapter.get_view_options(config.model, model) %}","handlingStrategy":"validation","validationCode":"{% if config.model is mapping and config.model.get('materialized') is defined %}\n  {% do adapter.get_view_options(config.model, model) %}\n{% endif %}","typeGuard":null,"tryCatchPattern":"{% set opts = adapter.get_view_options(config.model, model) %} wrapped in a Jinja try/except if available, falling back to {} on SerdeDeserializeError","preventionTips":["Pass config.model, never ad-hoc dicts","Keep config field names/types matching ModelConfig","Avoid quoted values in YAML that change types (e.g. 'true')","Sync ModelConfig schema changes with all custom macros"],"tags":["deserialization","jinja","config"],"backgroundTag":"schema-validation-failed","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}