dmtrKovalenko/fff · error
Failed to acquire frecency lock
Error message
Failed to acquire frecency lock: {} What it means
After successfully opening the frecency database, the tracker is installed into the shared global frecency slot via init(). This error means the lock acquisition or initialization of the shared frecency state failed; the underlying cause is included in the message. It is distinct from a failure to open the LMDB file itself.
Solutions
- Serialize instance creation (create instances sequentially or under an application-level mutex).
- Retry creation once; if the lock is poisoned, the process likely needs restart.
- Ensure only one instance initializes the shared frecency db, or use distinct frecency_db_path values per instance if supported.
- Check logs for a prior panic that could have poisoned the lock.
Example fix
// before instances = await Promise.all(paths.map(p => createInstance(p))); // after for (const p of paths) instances.push(createInstance(p)); // sequential init
Defensive patterns
Strategy: retry
Try / catch
try {
createInstanceWithFrecency(opts);
} catch (e) {
if (/Failed to acquire frecency lock/.test(e.message)) {
await delay(50);
return createInstanceWithFrecency(opts); // single retry after contention
}
throw e;
} Prevention
- Initialize instances sequentially, not in parallel.
- Use one shared instance instead of many.
- Avoid panicking inside init paths to prevent poisoned locks.
- Keep db paths per-instance when multiple instances are truly needed.
When it happens
Trigger: Calling fff_create_instance* concurrently from multiple threads/processes while another initialization holds the shared frecency lock and fails or contends; poisoned lock from a previous panic during init.
Common situations: Instantiating several instances in parallel at startup in the same process; a previous init panicked, leaving the mutex poisoned; embedded usage with multiple FFI entry points racing.
Related errors
- Failed to acquire query tracker lock
- Failed to acquire file picker 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/333eb1e397d50ef0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fff-c/src/lib.rs:222
}
}
let frecency_path = unsafe { optional_cstr(opts.frecency_db_path) }.map(|s| s.to_string());
let history_path = unsafe { optional_cstr(opts.history_db_path) }.map(|s| s.to_string());
let shared_picker = SharedFilePicker::default();
let shared_frecency = SharedFrecency::default();
let query_tracker = SharedQueryTracker::default();
if let Some(ref frecency_path) = frecency_path {
if let Some(parent) = PathBuf::from(frecency_path).parent() {
let _ = std::fs::create_dir_all(parent);
}
match FrecencyTracker::open(frecency_path) {
Ok(tracker) => {
if let Err(e) = shared_frecency.init(tracker) {
return FffResult::err(&format!("Failed to acquire frecency lock: {}", e));
}
}
Err(e) => return FffResult::err(&format!("Failed to init frecency db: {}", e)),
}
}
if let Some(ref history_path) = history_path {
if let Some(parent) = PathBuf::from(history_path).parent() {
let _ = std::fs::create_dir_all(parent);
}
match QueryTracker::open(history_path) {
Ok(tracker) => {
if let Err(e) = query_tracker.init(tracker) {
return FffResult::err(&format!("Failed to acquire query tracker lock: {}", e));
}
}
Err(e) => return FffResult::err(&format!("Failed to init query tracker db: {}", e)),View on GitHub (pinned to 7f8537e70f)