{"record":{"id":"1fc887aff4f13ac8","repo":"dmtrKovalenko/fff","slug":"failed-to-acquire-query-tracker-lock","errorCode":null,"errorMessage":"Failed to acquire query tracker lock: {}","messagePattern":"Failed to acquire query tracker lock: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fff-c/src/lib.rs","lineNumber":237,"sourceCode":"        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)),\n        }\n    }\n\n    let mode = if opts.ai_mode {\n        FFFMode::Ai\n    } else {\n        FFFMode::Neovim\n    };\n\n    let cache_budget = fff::ContentCacheBudget::from_overrides(\n        opts.cache_budget_max_files as usize,\n        opts.cache_budget_max_bytes,\n        opts.cache_budget_max_file_size,\n    );\n","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/dmtrKovalenko/fff/blob/7f8537e70f0ea1210f9acbbfc4640141105cdc78/crates/fff-c/src/lib.rs#L219-L255","documentation":"Analogous to the frecency case: QueryTracker::open succeeded but installing the tracker into the shared query-tracker slot via init() failed while acquiring its lock. The underlying lock error is embedded. Creation aborts since query history cannot be maintained.","triggerScenarios":"Concurrent fff_create_instance* calls racing on the shared query tracker; poisoned mutex from an earlier panic during query tracker init.","commonSituations":"Parallel instance creation at app startup; a panic in another thread earlier in the process poisoning the RwLock/Mutex; multiple bindings (Lua + Node) initializing in one host process.","solutions":["Create instances sequentially or guard creation with an app-level mutex.","Retry once; treat repeated lock errors (poisoned lock) as requiring process restart.","Avoid multiple components in the same process initializing the shared query tracker independently.","Investigate earlier panics in logs that may have poisoned the lock."],"exampleFix":"// before\n[createWithHistory(a), createWithHistory(b)].forEach(Promise.all);\n// after\ncreateWithHistory(a); createWithHistory(b); // one at a time","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  createInstanceWithHistory(opts);\n} catch (e) {\n  if (/Failed to acquire query tracker lock/.test(e.message)) {\n    await delay(50);\n    return createInstanceWithHistory(opts);\n  }\n  throw e;\n}","preventionTips":["Serialize instance creation in your bootstrap code.","Create only one instance per process that owns history.","Avoid panics during init to prevent lock poisoning.","If a poisoned lock persists, restart the host process."],"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"}