BoundaryML/baml · error

Invalid object type

Error message

Invalid object type

What it means

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'.

Solutions

  1. Ensure the caller passes a valid, non-null BamlObjectHandle obtained from the corresponding encode/constructor call
  2. Check that the handle's type tag matches the Rust type being decoded into
  3. Re-verify the enum of object types passed to generate_encode_decode_impls includes the type you are decoding
  4. Add debug logging of the handle tag at the decode boundary to identify mismatches

Example fix

// before
let value = MyType::decode(handle)?; // panics/errors on wrong or null handle
// after
if handle.is_null() {
    return Err(anyhow::anyhow!("received null BamlObjectHandle"));
}
let value = MyType::decode(handle)
    .map_err(|e| anyhow::anyhow!("decode failed for handle {:?}: {e}", handle.kind()))?;
Defensive patterns

Strategy: try-catch

Validate before calling

if handle.is_null() { return Err(anyhow!("null BamlObjectHandle")); }

Type guard

fn is_valid_handle(h: &BamlObjectHandle) -> bool { !h.as_ptr().is_null() && h.kind() == ExpectedKind::MyType }

Try / catch

let value = MyType::decode(handle).context("failed to decode handle from C boundary")?;

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/0d36aba4b5937859. Report an issue: GitHub.

Appendix: source

Thrown at engine/baml_cffi_macros/src/lib.rs:1622

                    }
                })
            } else {
                None
            }
        })
        .collect();

    let expanded = quote! {
        impl Decode for RawPtrType {
            type From = BamlObjectHandle;

            fn decode(from: Self::From) -> Result<Self, anyhow::Error>
            where
                Self: Sized,
            {
                match from.object {
                    #(#decode_arms)*
                    None => Err(anyhow::anyhow!("Invalid object type")),
                }
            }
        }

        impl Encode<BamlObjectHandle> for RawPtrType {
            fn encode(self) -> BamlObjectHandle {
                match self {
                    #(#encode_arms,)*
                }
            }
        }

        #(#wrapper_impls)*
    };

    TokenStream::from(expanded)
}

View on GitHub (pinned to bd85ce9dee)