{"record":{"id":"333eb1e397d50ef0","repo":"dmtrKovalenko/fff","slug":"failed-to-acquire-frecency-lock","errorCode":null,"errorMessage":"Failed to acquire frecency lock: {}","messagePattern":"Failed to acquire frecency lock: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fff-c/src/lib.rs","lineNumber":222,"sourceCode":"        }\n    }\n\n    let frecency_path = unsafe { optional_cstr(opts.frecency_db_path) }.map(|s| s.to_string());\n    let history_path = unsafe { optional_cstr(opts.history_db_path) }.map(|s| s.to_string());\n\n    let shared_picker = SharedFilePicker::default();\n    let shared_frecency = SharedFrecency::default();\n    let query_tracker = SharedQueryTracker::default();\n\n    if let Some(ref frecency_path) = frecency_path {\n        if let Some(parent) = PathBuf::from(frecency_path).parent() {\n            let _ = std::fs::create_dir_all(parent);\n        }\n\n        match FrecencyTracker::open(frecency_path) {\n            Ok(tracker) => {\n                if let Err(e) = shared_frecency.init(tracker) {\n                    return FffResult::err(&format!(\"Failed to acquire frecency lock: {}\", e));\n                }\n            }\n            Err(e) => return FffResult::err(&format!(\"Failed to init frecency db: {}\", e)),\n        }\n    }\n\n    if let Some(ref history_path) = history_path {\n        if let Some(parent) = PathBuf::from(history_path).parent() {\n            let _ = std::fs::create_dir_all(parent);\n        }\n\n        match QueryTracker::open(history_path) {\n            Ok(tracker) => {\n                if let Err(e) = query_tracker.init(tracker) {\n                    return FffResult::err(&format!(\"Failed to acquire query tracker lock: {}\", e));\n                }\n            }\n            Err(e) => return FffResult::err(&format!(\"Failed to init query tracker db: {}\", e)),","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/dmtrKovalenko/fff/blob/7f8537e70f0ea1210f9acbbfc4640141105cdc78/crates/fff-c/src/lib.rs#L204-L240","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ninstances = await Promise.all(paths.map(p => createInstance(p)));\n// after\nfor (const p of paths) instances.push(createInstance(p)); // sequential init","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  createInstanceWithFrecency(opts);\n} catch (e) {\n  if (/Failed to acquire frecency lock/.test(e.message)) {\n    await delay(50);\n    return createInstanceWithFrecency(opts); // single retry after contention\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["rust","concurrency","lock","ffi"],"backgroundTag":"database-initialization-failed","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"}