{"record":{"id":"7cf4da9f83629b17","repo":"dbt-labs/dbt-core","slug":"get-table-options-failed-to-deserialize-internald-7cf4da","errorCode":null,"errorMessage":"get_table_options: Failed to deserialize InternalDbtNodeWrapper: {e}","messagePattern":"get_table_options: Failed to deserialize InternalDbtNodeWrapper: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-adapter/src/relation/relation_object.rs","lineNumber":772,"sourceCode":"                    return Err(minijinja::Error::new(\n                        minijinja::ErrorKind::InvalidOperation,\n                        \"'materialized_view_from_relation_config' can only be invoked using the BigQuery adapter\",\n                    ));\n                }\n\n                let iter = ArgsIter::new(\n                    \"Relation.materialized_view_from_relation_config\",\n                    &[\"local_config\"],\n                    args,\n                );\n                let local_config_value = iter.next_arg::<&Value>()?;\n                iter.finish()?;\n\n                let local_config = minijinja_value_to_typed_struct::<InternalDbtNodeWrapper>(\n                    local_config_value.clone(),\n                )\n                .map_err(|e| {\n                    minijinja::Error::new(\n                        minijinja::ErrorKind::SerdeDeserializeError,\n                        format!(\n                            \"get_table_options: Failed to deserialize InternalDbtNodeWrapper: {e}\"\n                        ),\n                    )\n                })?;\n\n                let loader =\n                    crate::relation::bigquery::config::relation_types::materialized_view::new_loader();\n                let relation_config = loader\n                    .from_local_config(local_config.as_internal_node())\n                    .map_err(|err| {\n                        minijinja::Error::new(\n                            minijinja::ErrorKind::InvalidOperation,\n                            format!(\"error while loading local materialized view config: {err}\"),\n                        )\n                    })?;\n                Ok(Value::from_object(relation_config))","sourceCodeStart":754,"sourceCodeEnd":790,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-adapter/src/relation/relation_object.rs#L754-L790","documentation":"When handling the `get_table_options` method, the object converts the Jinja `local_config` value into the typed `InternalDbtNodeWrapper` struct via serde. If the value's shape does not match the expected struct (missing `__dbt_internal_node` fields, wrong nesting, plain dict instead of internal node), the deserialization fails and this SerdeDeserializeError is raised, embedding the underlying serde message.","triggerScenarios":"Calling `relation.get_table_options(local_config)` where the `local_config` argument is a plain config dict / wrong value rather than an `InternalDbtNodeWrapper` produced by the node machinery.","commonSituations":"Passing `config.model` directly instead of the internal node wrapper; constructing the argument manually in a custom macro; version mismatch where the internal node shape changed between dbt versions.","solutions":["Pass the internal node wrapper (e.g. `config.model` as provided by dbt's internal machinery), not a plain dictionary.","Inspect the embedded serde message in the error to identify which field of InternalDbtNodeWrapper did not match and fix the caller accordingly.","Upgrade/align the custom macro with the expected internal node structure for the installed dbt version."],"exampleFix":"// before\n{{ relation.get_table_options(config.model.config) }}\n// after\n{{ relation.get_table_options(config.model) }}","handlingStrategy":"validation","validationCode":"// Verify the argument is the internal node wrapper before calling\n{% if config.model is none %}{% do exceptions.raise_compiler_error('model node required') %}{% endif %}","typeGuard":"// Rust\fn is_internal_node(v: &Value) -> bool {\n    v.get_attr(\"__dbt_internal_node\").is_ok()\n}","tryCatchPattern":"match minijinja_value_to_typed_struct::<InternalDbtNodeWrapper>(v.clone()) {\n    Ok(w) => ..., \n    Err(e) => log::warn!(\"bad node wrapper: {e}\"),\n}","preventionTips":["Always pass dbt's internal node objects to get_table_options, never plain dicts.","Pin adapter and dbt-core versions together to avoid internal-shape drift.","Read the embedded serde error to pinpoint the mismatched field."],"tags":["serde","deserialization","jinja","bigquery"],"backgroundTag":"json-unmarshal-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"}