dmtrKovalenko/fff · error
Instance handle is null. Create one with…
Error message
Instance handle is null. Create one with fff_create_instance first.
What it means
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.
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.
Example fix
// before
const res = fff_search(null, query);
// after
const handle = fff_create_instance(opts);
if (handle === null) throw new Error('failed to create fff instance');
const res = fff_search(handle, query); Defensive patterns
Strategy: type-guard
Validate before calling
if (handle === null || handle === undefined) throw new Error('fff instance not created; call fff_create_instance first'); Type guard
function hasInstance(h) { return h !== null && h !== undefined && !h.equals(ffi.NULL); } Try / catch
if (!hasInstance(handle)) {
throw new Error('fff instance handle missing; create it with fff_create_instance first');
}
const res = fff_search(handle, query);
if (!res.ok) handleFffError(res); Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- opts is null
- Unsupported FffCreateOptions version
- opts.base_path is null or empty
- Failed to init tracing
- Failed to acquire frecency lock
AI-assisted analysis of dmtrKovalenko/fff@7f8537e70f (2026-09-10).
Data as JSON: /api/errors/ed535fab9cd73375.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fff-c/src/lib.rs:63
if s.is_null() {
None
} else {
unsafe { CStr::from_ptr(s).to_str().ok() }
}
}
/// Optional C string param: `None` if null, empty, or invalid UTF-8.
unsafe fn optional_cstr<'a>(s: *const c_char) -> Option<&'a str> {
unsafe { cstr_to_str(s) }.filter(|s| !s.is_empty())
}
/// Recover a `&FffInstance` from the opaque pointer; error `FffResult` if null.
pub(crate) unsafe fn instance_ref<'a>(
fff_handle: *mut c_void,
) -> Result<&'a FffInstance, *mut FffResult> {
if fff_handle.is_null() {
Err(FffResult::err(
"Instance handle is null. Create one with fff_create_instance first.",
))
} else {
Ok(unsafe { &*(fff_handle as *const FffInstance) })
}
}
/// Decode a `u8` grep mode into the core enum.
fn grep_mode_from_u8(mode: u8) -> fff::GrepMode {
match mode {
1 => fff::GrepMode::Regex,
2 => fff::GrepMode::Fuzzy,
_ => fff::GrepMode::PlainText,
}
}
/// Apply "0 means default" convention.
fn default_u32(val: u32, default: u32) -> u32 {
if val == 0 { default } else { val }View on GitHub (pinned to 7f8537e70f)