xai-org/grok-build · error
grove daemon unreachable
Error message
grove daemon unreachable
What it means
cancel_worktree_create first pings the grove daemon; if the ping fails it bails with 'grove daemon unreachable' before sending the CancelWorktreeCreate RPC. This means the client cannot reach the daemon that owns in-flight worktree creations, so the cancel request was never attempted.
Source
Thrown at crates/codegen/xai-fast-worktree/src/nfs/client.rs:237
storage_full: body.storage_full,
unknown: false,
mount: body.mount,
}),
Ok(Response::Err(e)) if e.error.contains("unknown worktree_id") => Ok(QuerySnapshot {
phase: None,
declined: None,
storage_full: false,
unknown: true,
mount: None,
}),
Ok(Response::Err(e)) => Err(NfsTryError::Other(anyhow!(e.error))),
Err(e) => Err(NfsTryError::Other(e)),
}
}
pub fn cancel_worktree_create(&self, worktree_id: &str) -> Result<(), anyhow::Error> {
if !self.ping() {
anyhow::bail!("grove daemon unreachable");
}
let req = Request::CancelWorktreeCreate {
v: PROTOCOL_VERSION,
worktree_id: worktree_id.to_owned(),
};
match self.call(&req, REMOVE_RPC_TIMEOUT) {
Ok(Response::Ok(_)) => Ok(()),
Ok(Response::Err(e)) => Err(anyhow!(e.error)),
Err(e) => Err(e),
}
}
pub fn cleanup_worktree_create(&self, worktree_id: &str) -> Result<(), anyhow::Error> {
if !self.ping() {
anyhow::bail!("grove daemon unreachable");
}
let req = Request::CleanupWorktreeCreate {
v: PROTOCOL_VERSION,View on GitHub (pinned to bc7f02eddd)
Solutions
- Check the daemon is running and reachable: ping the configured socket/port (e.g. grove daemon status / ss -x | grep grove) and start it if stopped.
- Verify the socket path / address passed via NfsWorktreeOpts matches where the daemon is actually listening.
- Retry cancel_worktree_create with backoff — transient unreachability during daemon restart resolves itself.
- If the daemon is permanently gone, rely on the daemon's own journal/expiry (cleanup_worktree_create on next connect) instead of cancelling.
Example fix
// before: cancel immediately, bail on first unreachable daemon
client.cancel_worktree_create(&worktree_id)?;
// after: retry briefly before giving up
for _ in 0..5 {
match client.cancel_worktree_create(&worktree_id) {
Ok(()) => break,
Err(e) if e.to_string().contains("grove daemon unreachable") => std::thread::sleep(Duration::from_millis(500)),
Err(e) => return Err(e),
}
} Defensive patterns
Strategy: retry
Validate before calling
fn daemon_reachable(client: &NfsWorktreeClient) -> bool { client.ping() } Try / catch
retry_with_backoff(5, Duration::from_millis(500), || {
client.cancel_worktree_create(&worktree_id)
}).map_err(|e| e.context("grove daemon unreachable; cancel not delivered"))?; Prevention
- Ping the daemon before issuing lifecycle RPCs.
- Run the grove daemon under a supervisor (systemd) so it auto-restarts.
- Keep NfsWorktreeOpts socket path in sync with daemon config.
- Log deferrals instead of failing hard during shutdown.
When it happens
Trigger: Calling NfsWorktreeClient::cancel_worktree_create while the grove daemon is down, restarting, listening on a different socket/port than configured, or blocked by permissions/firewall — ping() returns false and the error is raised.
Common situations: Daemon crashed or was restarted between create and cancel; stale NfsWorktreeClient constructed against an old socket path; daemon still starting during early shutdown/cleanup; container restarted and the grove socket vanished.
Related errors
- {}
- {} failed: {}
- runtime-socket deny resolution failed: {error}
- OIDC expires_in out of range: {secs}
- OIDC endpoint rejected request ({status}): {body}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/926ec076e2d78a2b.
Report an issue: GitHub.