{"record":{"id":"54d2e7ae243ee865","repo":"BoundaryML/baml","slug":"0-handle","errorCode":null,"errorMessage":"{0}","messagePattern":"\\{0\\}","errorType":"error_code","errorClass":"HandleError","httpStatus":null,"severity":"error","filePath":"baml_language/crates/bridge_cffi/src/handle.rs","lineNumber":24,"sourceCode":"use 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}\n","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/baml_language/crates/bridge_cffi/src/handle.rs#L6-L42","documentation":"HandleError::InvalidInput(String) is a pass-through variant whose message is the formatted payload itself (`#[error(\"{0}\")]` at handle.rs:24). It is produced by validate_input/validate_media_input when a string argument passed over the FFI boundary contains an embedded NUL byte ('\\0'), which C string conventions cannot represent.","triggerScenarios":"Calling media_from_url, media_from_file, or media_from_base64 with a url/file/base64 string (or optional mime_type) containing a '\\0' character; e.g. base64 blobs or URLs assembled from unchecked user or binary input.","commonSituations":"Base64 media payloads built from raw bytes including terminators; URLs copied from binary data; MIME types with stray control characters; passing Rust Strings through C-ABI where embedded NULs are illegal.","solutions":["Strip or reject embedded NUL bytes before calling the FFI media constructors.","Find the source of the '\\0' (usually a binary buffer converted to a string without sanitization) and fix the producer.","Re-encode media content (e.g. proper base64 without padding/NUL artifacts) before passing it.","If NUL is intentional, pass the data via a length-prefixed channel rather than a C string."],"exampleFix":"// before\nlet url = std::str::from_utf8(&bytes)?; // may contain '\\0'\nmedia_from_url(MediaKind::Generic, url, None)?;\n// after\nlet url = std::str::from_utf8(&bytes)?.trim_end_matches('\\0');\nif url.contains('\\0') { return Err(\"url contains NUL\"); }\nmedia_from_url(MediaKind::Generic, url, None)?;","handlingStrategy":"validation","validationCode":"def sanitize_for_ffi(s: str, field: str) -> str:\n    if \"\\0\" in s:\n        raise ValueError(f\"{field} contains an embedded NUL byte\")\n    return s","typeGuard":null,"tryCatchPattern":"try:\n    h = bridge.media_from_base64(MediaKind.Generic, b64, None)\nexcept HandleError as e:\n    if \"NUL\" in str(e):\n        b64 = b64.replace(\"\\0\", \"\")\n        h = bridge.media_from_base64(MediaKind.Generic, b64, None)\n    else:\n        raise","preventionTips":["Strip trailing/inner NULs from any string derived from binary buffers before FFI calls","Validate media URLs and MIME types at your API boundary","Prefer bytes-aware encoding helpers over naive str(bytes) conversions"],"tags":["ffi","validation","rust","string"],"backgroundTag":"invalid-argument-value","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"}