dmtrKovalenko/fff · error
Failed to acquire file picker lock
Error message
Failed to acquire file picker lock: {} What it means
fff_search takes a read lock on the instance's RwLock-protected FilePicker; if the underlying lock primitive returns Err (a poisoned lock, i.e. a writer panicked while holding it), the FFI layer converts that into this error rather than propagating the panic.
Solutions
- Find and fix the panic in the thread that poisoned the lock (check logs from the watcher/index threads).
- Recreate the instance: destroy the poisoned one with fff_destroy_instance and call fff_create_instance again.
- Restart the host process if instance recreation is not feasible.
- Report the underlying panic to the library maintainers if it reproduces — lock poisoning here indicates an internal bug.
Example fix
null
Defensive patterns
Strategy: retry
Try / catch
local res = fff.search(inst, q)
if res.is_err and res.message:find('lock') then
recreate_instance_and_retry()
end Prevention
- Avoid panicking inside callbacks that run while holding picker locks.
- Recreate instances after any observed panic in watcher threads.
- Report reproducible panics upstream — poisoning signals an internal bug.
When it happens
Trigger: Calling fff_search (or any picker access) on an instance whose picker RwLock was poisoned by a panic in another thread — typically a background watcher or a previous FFI call that panicked while holding the write lock.
Common situations: A previous index operation panicked (bug in a watcher callback) leaving the lock poisoned; multi-threaded embedding where one thread crashed mid-update; using an instance handle after a failed background operation.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Failed to acquire frecency lock
- Failed to acquire query tracker lock
- Instance handle is null. Create one with…
- opts is null
- Unsupported FffCreateOptions version
AI-assisted analysis of dmtrKovalenko/fff@7f8537e70f (2026-09-10).
Data as JSON: /api/errors/1d6a3ac3cfef62fd.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fff-c/src/lib.rs:363
) -> *mut FffResult {
let inst = match unsafe { instance_ref(fff_handle) } {
Ok(i) => i,
Err(e) => return e,
};
let query_str = match unsafe { cstr_to_str(query) } {
Some(s) => s,
None => return FffResult::err("Query is null or invalid UTF-8"),
};
let current_file_str = unsafe { optional_cstr(current_file) };
let page_size = default_u32(page_size, 100) as usize;
let min_combo_count = default_u32(min_combo_count, 3);
let combo_boost_multiplier = default_i32(combo_boost_multiplier, 100);
let picker_guard = match inst.picker.read() {
Ok(g) => g,
Err(e) => return FffResult::err(&format!("Failed to acquire file picker lock: {}", e)),
};
let picker = match picker_guard.as_ref() {
Some(p) => p,
None => {
return FffResult::err("File picker not initialized. Call fff_create_instance first.");
}
};
// Get query tracker ref for combo matching
let qt_guard = match inst.query_tracker.read() {
Ok(q) => q,
Err(_) => return FffResult::err("Failed to acquire query tracker lock"),
};
let query_tracker_ref = qt_guard.as_ref();
let parser = QueryParser::default();
let parsed = parser.parse(query_str);View on GitHub (pinned to 7f8537e70f)