{"record":{"id":"dfb4254b138111fa","repo":"atuinsh/atuin","slug":"timed-out-waiting-for-lock-at","errorCode":null,"errorMessage":"timed out waiting for lock at {}","messagePattern":"timed out waiting for lock at (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/atuin/src/command/client/daemon.rs","lineNumber":214,"sourceCode":"    let file = open_lock_file(path)?;\n\n    let outcome = Backoff::Linear(LOCK_POLL)\n        .retry_sync(\n            || match file.try_lock() {\n                Ok(()) => ControlFlow::Break(Ok(())),\n                Err(TryLockError::WouldBlock) => ControlFlow::Continue(()),\n                Err(TryLockError::Error(err)) => {\n                    ControlFlow::Break(Err(eyre!(\"could not lock {}: {err}\", path.display())))\n                }\n            },\n            timeout,\n        )\n        .await;\n\n    match outcome {\n        Ok(Ok(())) => Ok(file),\n        Ok(Err(err)) => Err(err),\n        Err(()) => bail!(\"timed out waiting for lock at {}\", path.display()),\n    }\n}\n\nasync fn wait_for_pidfile_available(path: &Path, timeout: Duration) -> Result<()> {\n    let file = wait_for_lock(path, timeout).await?;\n    file.unlock().wrap_err_with(|| format!(\"failed to unlock {}\", path.display()))?;\n    Ok(())\n}\n\nasync fn connect_client(settings: &Settings) -> Result<HistoryClient> {\n    HistoryClient::new(\n        #[cfg(not(unix))]\n        settings.daemon.tcp_port,\n        #[cfg(unix)]\n        settings.daemon.existing_socket_path().into_owned(),\n    )\n    .await\n}","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/atuinsh/atuin/blob/900007c48045867e7f44b0f9bc55ad9dbe99ee0d/crates/atuin/src/command/client/daemon.rs#L196-L232","documentation":"`wait_for_lock` awaits the pidfile flock with a timeout; if the timeout elapses (`outcome` is `Err(())`), it bails with 'timed out waiting for lock'. This happens when another process holds the lock for longer than the caller's timeout while trying to become the daemon or wait for the pidfile to become available.","triggerScenarios":"`wait_for_pidfile_available` or `ensure_daemon_running` waiting on a pidfile whose owner process keeps the lock beyond the configured timeout — a hung/busy daemon, a deadlocked daemon, or heavy lock contention.","commonSituations":"Daemon startup stalled (e.g. slow bind, hung runtime) so the lock is never released or acquired; another user's daemon on a shared HOME; filesystem where flock behaves oddly (some network filesystems).","solutions":["Check whether the daemon process is alive and healthy (`pgrep -a atuin`, logs).","Kill/stop a hung daemon (`pkill -9 atuin` if necessary) and retry.","Increase any relevant daemon timeout settings or retry the command after a moment.","Verify the pidfile is on a local filesystem (flock on NFS/network mounts is unreliable).","Move to a separate ATUIN_HOME if another session's daemon owns the lock."],"exampleFix":"# before\natuin daemon  # hangs, then: timed out waiting for lock at ...\npkill -9 atuin\n# after\npkill -9 atuin && atuin daemon   # clear the stale lock holder first","handlingStrategy":"retry","validationCode":"# verify lock holder is alive before waiting\nfuser -v ~/.local/share/atuin/daemon.pid 2>/dev/null || echo \"no holder; safe to start\"","typeGuard":null,"tryCatchPattern":"match atuin::daemon::ensure_running() {\n    Err(e) if e.to_string().contains(\"timed out waiting for lock\") => {\n        std::thread::sleep(Duration::from_secs(2));\n        retry_with_backoff(3);\n    }\n    Err(e) => return Err(e),\n    Ok(_) => {}\n}","preventionTips":["Monitor daemon health so hung processes are detected early.","Keep pidfiles on local filesystems, not NFS.","Kill stale/hung daemons before retrying.","Bound waits with retry + backoff in scripts."],"tags":["daemon","file-lock","timeout"],"backgroundTag":"request-timeout","analyzedSha":"900007c48045867e7f44b0f9bc55ad9dbe99ee0d","analyzedAt":"2026-09-19T12:52:51.491Z","contentChangedAt":"2026-09-19T12:52:51.491Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}