xai-org/grok-build · info
Another leader already holds the lock at {}
Error message
Another leader already holds the lock at {} What it means
run_leader detected, via crate::leader::listener_is_ready, that another process already holds the leader lock with a bound IPC socket at the given path. This is the single-instance guard of the agent: instead of fighting for leadership, this process logs and returns an error so the caller exits and the client adopts the existing leader. It is an expected, by-design outcome of launching a second agent instance, not a fault.
Source
Thrown at crates/codegen/xai-grok-shell/src/agent/app.rs:791
});
let mut agent_config = agent_config.clone();
agent_config.mode = crate::agent::config::AgentMode::Leader;
let ws_url = &agent_config.grok_com_config.grok_ws_url;
let mut lock = LeaderLock::new(ws_url);
let socket_path = lock.socket_path().clone();
match lock.try_acquire() {
Ok(true) => {
lock.write_pid()?;
debug!("Acquired leader lock, proceeding as leader");
}
Ok(false) => {
if crate::leader::listener_is_ready(&socket_path) {
info!(
"Another process holds the leader lock with a bound socket ({}). \
Exiting so the client adopts it.",
socket_path.display()
);
return Err(anyhow::anyhow!(
"Another leader already holds the lock at {}",
socket_path.display()
));
}
match lock.acquire_reopen_timeout(LEADER_ACQUIRE_TIMEOUT).await {
Ok(()) => {
lock.write_pid()?;
debug!("Acquired leader lock after bounded wait, proceeding as leader");
}
Err(LockError::Timeout(_)) => {
info!(
"Timed out waiting for the leader lock ({}). Exiting so the \
client adopts whoever won it.",
socket_path.display()
);
return Err(anyhow::anyhow!(
"Timed out acquiring leader lock at {}",
socket_path.display()View on GitHub (pinned to bc7f02eddd)
Solutions
- Do nothing to fix — exit gracefully; the running leader is healthy and the client will adopt it.
- If you genuinely need a second independent agent, change the socket/lock path (e.g. a different XDG_RUNTIME_DIR or profile) so each instance has its own socket_path.
- If you believe no other agent is running, verify with `ss -xl | grep <socket-name>` or `lsof <socket_path>` to find the process holding the socket, then stop it.
- Remove a stale-but-live socket only after confirming the owner process is defunct.
Example fix
// before: treating second launch as a crash
run_agent_command(...).await?;
// after: treat this specific error as a graceful exit
if let Err(e) = run_agent_command(...).await {
if e.to_string().starts_with("Another leader already holds the lock") {
info!("leader already running; exiting so client adopts it");
return Ok(());
}
return Err(e);
} Defensive patterns
Strategy: fallback
Validate before calling
let socket_path = agent_socket_path();
if crate::leader::listener_is_ready(&socket_path) {
info!("leader already running at {}", socket_path.display());
return Ok(ExitCode::from(0)); // adopt existing leader
} Type guard
fn is_already_leader_err(e: &anyhow::Error) -> bool {
e.to_string().starts_with("Another leader already holds the lock")
} Try / catch
match run_agent_command(...).await {
Err(e) if is_already_leader_err(&e) => Ok(()), // expected: adopt existing leader
other => other,
} Prevention
- Treat this error as success in launchers/autostart scripts so double launches do not report failures.
- Never delete the socket file while a leader may be alive — probe listener_is_ready first.
- Give each profile/user its own socket path to avoid intentional cross-instance collisions.
When it happens
Trigger: Calling run_leader (via run_agent_command) when the socket_path already has a live listener bound by another agent process; specifically the check `crate::leader::listener_is_ready(&socket_path)` returns true before lock.acquire_reopen_timeout is attempted.
Common situations: Launching the agent twice (double shell startup, autostart entry plus manual run); a previous leader is still running normally; running an agent in multiple terminal tabs against the same XDG runtime dir.
Related errors
- unix socket path too long: {}
- Timed out acquiring leader lock at {}
- Failed to acquire leader lock: {}
- Timeout waiting for IPC socket to be created
- connect timed out
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/14007fefbf261513.
Report an issue: GitHub.