dmtrKovalenko/fff · error
Failed to acquire query tracker lock
Error message
Failed to acquire query tracker lock: {} What it means
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.
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.
Example fix
// before [createWithHistory(a), createWithHistory(b)].forEach(Promise.all); // after createWithHistory(a); createWithHistory(b); // one at a time
Defensive patterns
Strategy: retry
Try / catch
try {
createInstanceWithHistory(opts);
} catch (e) {
if (/Failed to acquire query tracker lock/.test(e.message)) {
await delay(50);
return createInstanceWithHistory(opts);
}
throw e;
} Prevention
- 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.
When it happens
Trigger: Concurrent fff_create_instance* calls racing on the shared query tracker; poisoned mutex from an earlier panic during query tracker init.
Common situations: 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.
Related errors
- Failed to acquire frecency 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/1fc887aff4f13ac8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fff-c/src/lib.rs:237
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)),
}
}
let mode = if opts.ai_mode {
FFFMode::Ai
} else {
FFFMode::Neovim
};
let cache_budget = fff::ContentCacheBudget::from_overrides(
opts.cache_budget_max_files as usize,
opts.cache_budget_max_bytes,
opts.cache_budget_max_file_size,
);
View on GitHub (pinned to 7f8537e70f)