{"record":{"id":"0d36aba4b5937859","repo":"BoundaryML/baml","slug":"invalid-object-type","errorCode":null,"errorMessage":"Invalid object type","messagePattern":"Invalid object type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml_cffi_macros/src/lib.rs","lineNumber":1622,"sourceCode":"                    }\n                })\n            } else {\n                None\n            }\n        })\n        .collect();\n\n    let expanded = quote! {\n        impl Decode for RawPtrType {\n            type From = BamlObjectHandle;\n\n            fn decode(from: Self::From) -> Result<Self, anyhow::Error>\n            where\n                Self: Sized,\n            {\n                match from.object {\n                    #(#decode_arms)*\n                    None => Err(anyhow::anyhow!(\"Invalid object type\")),\n                }\n            }\n        }\n\n        impl Encode<BamlObjectHandle> for RawPtrType {\n            fn encode(self) -> BamlObjectHandle {\n                match self {\n                    #(#encode_arms,)*\n                }\n            }\n        }\n\n        #(#wrapper_impls)*\n    };\n\n    TokenStream::from(expanded)\n}\n","sourceCodeStart":1604,"sourceCodeEnd":1640,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml_cffi_macros/src/lib.rs#L1604-L1640","documentation":"The baml_cffi_macros generated decoder converts an optional C object pointer (RawPtrType / BamlObjectHandle) back into the Rust wrapper type via generated match arms. `None` means the source object pointer was null or of an unexpected handle kind, so there is no representation to decode — reported as 'Invalid object type'.","triggerScenarios":"Calling the generated decode() on a BamlObjectHandle whose inner object is None (null pointer), or whose tag does not correspond to any decode arm generated for the type.","commonSituations":"FFI callers passing a null or already-freed handle across the C boundary; a handle created for a different baml object type being fed to the wrong decode impl after macro/enum changes.","solutions":["Ensure the caller passes a valid, non-null BamlObjectHandle obtained from the corresponding encode/constructor call","Check that the handle's type tag matches the Rust type being decoded into","Re-verify the enum of object types passed to generate_encode_decode_impls includes the type you are decoding","Add debug logging of the handle tag at the decode boundary to identify mismatches"],"exampleFix":"// before\nlet value = MyType::decode(handle)?; // panics/errors on wrong or null handle\n// after\nif handle.is_null() {\n    return Err(anyhow::anyhow!(\"received null BamlObjectHandle\"));\n}\nlet value = MyType::decode(handle)\n    .map_err(|e| anyhow::anyhow!(\"decode failed for handle {:?}: {e}\", handle.kind()))?;","handlingStrategy":"try-catch","validationCode":"if handle.is_null() { return Err(anyhow!(\"null BamlObjectHandle\")); }","typeGuard":"fn is_valid_handle(h: &BamlObjectHandle) -> bool { !h.as_ptr().is_null() && h.kind() == ExpectedKind::MyType }","tryCatchPattern":"let value = MyType::decode(handle).context(\"failed to decode handle from C boundary\")?;","preventionTips":["Always round-trip handles through the matching encode/decode pair","Null-check pointers at every FFI entry point","Regenerate CFFI impls after adding or reordering object types"],"tags":["ffi","macros","decode"],"backgroundTag":"type-mismatch","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}