BoundaryML/baml · error
Expected Collector, got {}
Error message
Expected Collector, got {} What it means
Thrown while decoding BamlFunctionArguments: the host passes a list of raw pointer objects expected to all be Collectors, but RawPtrType::decode resolved one of them to a different pointer type (the message includes the actual type name). This is a defensive check that the FFI object registry returns the right variant.
Source
Thrown at engine/language_client_cffi/src/ctypes/function_args_decode.rs:44
.kwargs
.into_iter()
.map(from_host_kv_to_baml_kv)
.collect::<Result<_, _>>()?;
let client_registry = from
.client_registry
.map(ClientRegistry::decode)
.transpose()?
.filter(|r| !r.is_empty());
let env_vars = from.env.into_iter().map(|e| (e.key, e.value)).collect();
let collectors = {
let collectors = from
.collectors
.into_iter()
.map(RawPtrType::decode)
.map(|r| match r {
Ok(RawPtrType::Collector(c)) => Ok(c),
Err(e) => Err(e),
Ok(other) => Err(anyhow::anyhow!("Expected Collector, got {}", other.name())),
})
.collect::<Result<Vec<_>, _>>()?;
if collectors.is_empty() {
None
} else {
Some(collectors)
}
};
let type_builder = from
.type_builder
.map(RawPtrType::decode)
.transpose()?
.map(|r| match r {
RawPtrType::TypeBuilder(t) => Ok(t),
other => Err(anyhow::anyhow!(
"Expected TypeBuilder, got {}",
other.name()
)),View on GitHub (pinned to bd85ce9dee)
Solutions
- Verify that the object you pass in the collectors argument is actually a Collector instance created via the BAML client's collector API
- Recreate the object if its handle may be stale, and avoid reusing pointer IDs across calls
- Align host SDK and engine versions so RawPtrType tags match what the decoder expects
Example fix
// before (host pseudocode) args.collectors = [type_builder] // wrong object // after args.collectors = [baml_collector] // actual Collector instance
Defensive patterns
Strategy: type-guard
Validate before calling
# host side
for c in collectors:
if not isinstance(c, Collector):
raise TypeError(f"collectors must contain Collector instances, got {type(c).__name__}") Type guard
function isCollector(obj) { return obj && obj.__baml_type === 'Collector'; }
const safeCollectors = maybeCollectors.filter(isCollector); Try / catch
try:
result = client.CallFunction(fn, args)
except Exception as e:
if "Expected Collector" in str(e):
raise TypeError("Pass only Collector objects in the collectors argument") from e
raise Prevention
- Pass only objects obtained from the client's Collector factory into collectors
- Do not reuse variable names that can shadow Collector handles with other BAML objects
- Reacquire handles after runtime restarts instead of caching them
When it happens
Trigger: Passing a non-Collector object (e.g. a TypeBuilder or runtime/client pointer) inside the collectors list of a function call's arguments.
Common situations: Mixing up object references in host code (passing the wrong handle/variable into a b.collectors-style argument), stale or recycled pointer IDs from the object registry, or version skew where pointer type tags shifted.
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
- Expected TypeBuilder, got {}
- Expected string value for tag key {}
- Key is missing
- Value is null for key {}
- Key must be a string
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/9ffc1e7379d3d6de.
Report an issue: GitHub.