{"record":{"id":"cc8402859d88bbb6","repo":"BoundaryML/baml","slug":"unsupported-handle-type","errorCode":null,"errorMessage":"unsupported handle type","messagePattern":"unsupported handle type","errorType":"error_code","errorClass":"HandleError","httpStatus":null,"severity":"error","filePath":"baml_language/crates/bridge_cffi/src/handle.rs","lineNumber":23,"sourceCode":"use bex_project::{BexExternalAdt, MediaKind, MediaValue};\nuse bridge_ctypes::{CffiHandleTableEntry, HANDLE_TABLE, baml_bridge::cffi::BamlHandleType};\n\n/// An owned handle-table key and its protocol type tag.\n#[derive(Clone, Copy, Debug, Eq, PartialEq)]\npub struct HandleParts {\n    pub key: u64,\n    pub handle_type: i32,\n}\n\n/// Failure from a safe ordinary handle or media operation.\n#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]\npub enum HandleError {\n    #[error(\"invalid handle\")]\n    InvalidHandle,\n    #[error(\"handle type mismatch\")]\n    TypeMismatch,\n    #[error(\"unsupported handle type\")]\n    UnsupportedHandleType,\n    #[error(\"{0}\")]\n    InvalidInput(String),\n}\n\nfn insert_entry(entry: CffiHandleTableEntry) -> HandleParts {\n    let handle_type = entry.handle_type() as i32;\n    let key = HANDLE_TABLE.insert(entry);\n    HandleParts { key, handle_type }\n}\n\nfn validate_input(value: &str, field: &str) -> Result<(), HandleError> {\n    if value.contains('\\0') {\n        return Err(HandleError::InvalidInput(format!(\n            \"{field} contains an embedded NUL byte\"\n        )));\n    }\n    Ok(())\n}","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bridge_cffi/src/handle.rs#L5-L41","documentation":"HandleError::UnsupportedHandleType is raised by the bridge_cffi handle layer when a media-access API (media_url, media_file, media_base64, media_mime_type) resolves a handle that exists in the handle table but holds something other than a media value (e.g. a function ref or engine-heap handle). resolve_media in handle.rs:62-65 matches only CffiHandleTableEntry::Adt(BexExternalAdt::Media); any other row variant hits the `_ => Err(HandleError::UnsupportedHandleType)` arm. It signals you called a media accessor on a non-media handle.","triggerScenarios":"Calling media_url/media_file/media_base64/media_mime_type with a (key, handle_type) pair whose table row is a FunctionRef or BexHeapHandle entry instead of a media entry — typically a key returned by seed_function_ref_handle/seed_heap_handle or minted for a function reference.","commonSituations":"Mixing up keys between media handles and function-ref/heap handles in FFI code; passing a stale or reassigned key from another subsystem; test harnesses reusing seeded keys across handle kinds.","solutions":["Verify which API produced the key; only media_from_url/media_from_file/media_from_base64 (and generic media seeds) yield media-capable handles.","Use the matching accessor for the handle kind (e.g. function-ref APIs for function-ref handles) instead of the media_* accessors.","Check the handle_type tag passed in matches the row's type; re-fetch the correct handle rather than guessing the key.","Enable debug logging / call handle_refcount-style instrumentation to confirm the row's actual variant."],"exampleFix":"// before\nlet media = media_base64(fn_ref_key, BamlHandleType::HandleMedia as i32)?; // UnsupportedHandleType\n// after\nlet media = media_base64(media_key, BamlHandleType::HandleMedia as i32)?;","handlingStrategy":"type-guard","validationCode":"def ensure_media_handle(key, handle_type, table):\n    entry = table.resolve(key)\n    if entry is None:\n        raise ValueError(\"unknown handle key\")\n    if entry.kind != \"media\":\n        raise ValueError(f\"handle {key} is {entry.kind}, not media\")","typeGuard":"def is_media_handle(entry) -> bool:\n    return isinstance(entry, CffiHandleTableEntry) and entry.variant == \"Adt\" and entry.adt_kind == \"Media\"","tryCatchPattern":"try:\n    url = bridge.media_url(key, handle_type)\nexcept HandleError as e:\n    if \"unsupported handle type\" in str(e):\n        url = None  # not a media handle; route to the appropriate accessor\n    else:\n        raise","preventionTips":["Track handle provenance: only use keys returned by media_from_* APIs with media_* accessors","Never reuse keys across handle kinds in test harnesses","Encode the handle kind in your host-side wrapper types instead of raw u64 keys"],"tags":["ffi","handle","rust","bridge"],"backgroundTag":"unsupported-operation","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}