BoundaryML/baml · error · HandleError
handle type mismatch
Error message
handle type mismatch
What it means
HandleError::TypeMismatch from handle.rs. The handle is valid and live, but its handle_type does not match what the operation requires — e.g. passing a runtime handle where a media handle is expected. The bridge checks the type tag on every handle use.
Source
Thrown at baml_language/crates/bridge_cffi/src/handle.rs:21
use std::sync::Arc;
use bex_project::{BexExternalAdt, MediaKind, MediaValue};
use bridge_ctypes::{CffiHandleTableEntry, HANDLE_TABLE, baml_bridge::cffi::BamlHandleType};
/// An owned handle-table key and its protocol type tag.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct HandleParts {
pub key: u64,
pub handle_type: i32,
}
/// Failure from a safe ordinary handle or media operation.
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
pub enum HandleError {
#[error("invalid handle")]
InvalidHandle,
#[error("handle type mismatch")]
TypeMismatch,
#[error("unsupported handle type")]
UnsupportedHandleType,
#[error("{0}")]
InvalidInput(String),
}
fn insert_entry(entry: CffiHandleTableEntry) -> HandleParts {
let handle_type = entry.handle_type() as i32;
let key = HANDLE_TABLE.insert(entry);
HandleParts { key, handle_type }
}
fn validate_input(value: &str, field: &str) -> Result<(), HandleError> {
if value.contains('\0') {
return Err(HandleError::InvalidInput(format!(
"{field} contains an embedded NUL byte"
)));
}View on GitHub (pinned to bd85ce9dee)
Solutions
- Pass the handle kind the API expects — check which create_* call produced it.
- Keep handles in distinct, typed variables instead of reusing one.
- Check handle_type on the handle struct before the call.
- Use strongly typed wrapper bindings rather than raw integers.
Example fix
// before let h = runtime_handle; // handle_type = RUNTIME media_read(h); // after let h = media_handle; // handle_type = MEDIA media_read(h);
Defensive patterns
Strategy: type-guard
Validate before calling
if handle.handle_type != EXPECTED_HANDLE_TYPES['media_read']:
raise TypeError('wrong handle kind for media_read') Type guard
def is_media_handle(handle) -> bool:
return handle.handle_type == HandleType.MEDIA Try / catch
try:
result = bridge.media_read(handle)
except BridgeError as e:
if e is HandleError.TypeMismatch:
log.error('passed wrong handle kind; check create_* origin') Prevention
- Keep one variable per handle kind
- Wrap raw handle ints in typed wrapper classes
- Check handle_type before any handle-consuming call
When it happens
Trigger: Passing a handle of the wrong kind to a typed operation (e.g. a function/runtime handle to a media API or vice versa); reusing one handle variable across differently-typed calls; bindings that lose the type distinction and use a single int everywhere.
Common situations: Copy-pasted call code reusing the wrong handle variable; untyped FFI bindings (plain integers) that make cross-typing easy; refactors that changed which object a handle refers to.
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
- baml.panics.HostContractViolation
- invalid handle
- unsupported handle type
- Invalid handle key: {0}
- unsupported raw pointer type
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/eb2da4ad82ae736d.
Report an issue: GitHub.