{"record":{"id":"12a8a3604f7e0886","repo":"dbt-labs/dbt-core","slug":"failed-to-downcast-response","errorCode":null,"errorMessage":"Failed to downcast response","messagePattern":"Failed to downcast response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dbt-adapter/src/response.rs","lineNumber":370,"sourceCode":"            let is_known = key.as_str().is_some_and(|s| KNOWN_KEYS.contains(&s));\n            if !is_known {\n                keys.push(key.clone());\n            }\n        }\n        Enumerator::Iter(Box::new(keys.into_iter()))\n    }\n}\n\nimpl TryFrom<Value> for AdapterResponse {\n    type Error = minijinja::Error;\n\n    fn try_from(value: Value) -> Result<Self, Self::Error> {\n        if let Some(response) = value.downcast_object::<AdapterResponse>() {\n            Ok((*response).clone())\n        } else if let Some(message_str) = value.as_str() {\n            Ok(AdapterResponse::new().with_message(message_str))\n        } else {\n            Err(minijinja::Error::new(\n                minijinja::ErrorKind::CannotDeserialize,\n                \"Failed to downcast response\",\n            ))\n        }\n    }\n}\n\n/// load_result response object\n#[derive(Debug)]\npub struct ResultObject {\n    pub response: AdapterResponse,\n    pub table: Option<AgateTable>,\n    #[allow(unused)]\n    pub data: Option<Value>,\n}\n\nimpl ResultObject {\n    pub fn new(response: AdapterResponse, table: Option<AgateTable>) -> Self {","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-adapter/src/response.rs#L352-L388","documentation":"This `TryFrom<Value>` conversion for `AdapterResponse` succeeds only if the value is an `AdapterResponse` object or a plain string (treated as the response message). Any other minijinja Value falls through to this CannotDeserialize error, meaning the value could not be downcast to an adapter response.","triggerScenarios":"Converting a Jinja `Value` into `AdapterResponse` where the value is neither an AdapterResponse object nor a string — e.g. a dict returned by a custom adapter callback, a number, or a serialized response map.","commonSituations":"Custom adapter/materialization code returning a dict or non-standard response from an `execute`/statement callback; plugin code that wraps the response in another object type after an adapter upgrade.","solutions":["Return an `AdapterResponse` object from the adapter callback, or a plain string message.","If you control the caller, inspect the value's actual type (log its kind) and normalize it before conversion.","Check for adapter/plugin version mismatches that changed the response object type expected by this conversion."],"exampleFix":"// before\nOk(Value::from_object(serde_json::json!({\"message\": \"OK\"})))\n// after\nOk(Value::from_object(AdapterResponse::new().with_message(\"OK\")))","handlingStrategy":"type-guard","validationCode":"// Rust\nfn is_adapter_response(v: &Value) -> bool {\n    v.downcast_object::<AdapterResponse>().is_some() || v.as_str().is_some()\n}","typeGuard":"fn as_adapter_response(v: Value) -> Option<AdapterResponse> {\n    v.downcast_object::<AdapterResponse>().map(|o| (*o).clone())\n        .or_else(|| v.as_str().map(|m| AdapterResponse::new().with_message(m.to_string())))\n}","tryCatchPattern":"match AdapterResponse::try_from(value) {\n    Ok(resp) => ..., \n    Err(e) => log::warn!(\"response not downcastable: {e}\"),\n}","preventionTips":["Always return AdapterResponse (or a string) from adapter execute callbacks.","Avoid wrapping responses in dicts or intermediate objects in custom materializations.","Keep custom adapters aligned with the AdapterResponse API of the installed adapter crate."],"tags":["downcast","adapter-response","deserialization"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}