{"record":{"id":"ed535fab9cd73375","repo":"dmtrKovalenko/fff","slug":"instance-handle-is-null-create-one-with-fff-creat","errorCode":null,"errorMessage":"Instance handle is null. Create one with fff_create_instance first.","messagePattern":"Instance handle is null\\. Create one with fff_create_instance first\\.","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fff-c/src/lib.rs","lineNumber":63,"sourceCode":"    if s.is_null() {\n        None\n    } else {\n        unsafe { CStr::from_ptr(s).to_str().ok() }\n    }\n}\n\n/// Optional C string param: `None` if null, empty, or invalid UTF-8.\nunsafe fn optional_cstr<'a>(s: *const c_char) -> Option<&'a str> {\n    unsafe { cstr_to_str(s) }.filter(|s| !s.is_empty())\n}\n\n/// Recover a `&FffInstance` from the opaque pointer; error `FffResult` if null.\npub(crate) unsafe fn instance_ref<'a>(\n    fff_handle: *mut c_void,\n) -> Result<&'a FffInstance, *mut FffResult> {\n    if fff_handle.is_null() {\n        Err(FffResult::err(\n            \"Instance handle is null. Create one with fff_create_instance first.\",\n        ))\n    } else {\n        Ok(unsafe { &*(fff_handle as *const FffInstance) })\n    }\n}\n\n/// Decode a `u8` grep mode into the core enum.\nfn grep_mode_from_u8(mode: u8) -> fff::GrepMode {\n    match mode {\n        1 => fff::GrepMode::Regex,\n        2 => fff::GrepMode::Fuzzy,\n        _ => fff::GrepMode::PlainText,\n    }\n}\n\n/// Apply \"0 means default\" convention.\nfn default_u32(val: u32, default: u32) -> u32 {\n    if val == 0 { default } else { val }","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/dmtrKovalenko/fff/blob/7f8537e70f0ea1210f9acbbfc4640141105cdc78/crates/fff-c/src/lib.rs#L45-L81","documentation":"The C FFI instance_ref helper converts the opaque void* handle into a &FffInstance. A null handle means no instance was ever created (or it was freed), so any search/glob/grep call fails immediately. The library requires fff_create_instance first.","triggerScenarios":"Calling fff_search, fff_glob, fff_search_directories, fff_search_mixed, fff_live_grep_ex, or fff_multi_grep_ex with a null/zeroed handle, or a handle from a failed fff_create_instance call, or after fff_free_instance double-use.","commonSituations":"Ignoring the error result of fff_create_instance and proceeding with the null handle; FFI marshalling bug in a binding layer dropping the pointer; using the handle after library shutdown.","solutions":["Check the FffResult from fff_create_instance before using the handle.","Ensure the handle returned by fff_create_instance is stored and passed to every subsequent call.","In bindings, guard against null before calling search functions (throw a clear error instead).","Verify create/free ordering so the handle is not used after being freed."],"exampleFix":"// before\nconst res = fff_search(null, query);\n// after\nconst handle = fff_create_instance(opts);\nif (handle === null) throw new Error('failed to create fff instance');\nconst res = fff_search(handle, query);","handlingStrategy":"type-guard","validationCode":"if (handle === null || handle === undefined) throw new Error('fff instance not created; call fff_create_instance first');","typeGuard":"function hasInstance(h) { return h !== null && h !== undefined && !h.equals(ffi.NULL); }","tryCatchPattern":"if (!hasInstance(handle)) {\n  throw new Error('fff instance handle missing; create it with fff_create_instance first');\n}\nconst res = fff_search(handle, query);\nif (!res.ok) handleFffError(res);","preventionTips":["Always check the result of fff_create_instance before searching.","Store the handle in a singleton/manager object.","Never use the handle after freeing the instance.","Null-check handles in every FFI wrapper."],"tags":["ffi","rust","c","null-pointer"],"backgroundTag":"null-argument","analyzedSha":"7f8537e70f0ea1210f9acbbfc4640141105cdc78","analyzedAt":"2026-09-10T07:26:53.407Z","contentChangedAt":"2026-09-10T07:26:53.407Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}