{"record":{"id":"926ec076e2d78a2b","repo":"xai-org/grok-build","slug":"grove-daemon-unreachable","errorCode":null,"errorMessage":"grove daemon unreachable","messagePattern":"grove daemon unreachable","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-fast-worktree/src/nfs/client.rs","lineNumber":237,"sourceCode":"                storage_full: body.storage_full,\n                unknown: false,\n                mount: body.mount,\n            }),\n            Ok(Response::Err(e)) if e.error.contains(\"unknown worktree_id\") => Ok(QuerySnapshot {\n                phase: None,\n                declined: None,\n                storage_full: false,\n                unknown: true,\n                mount: None,\n            }),\n            Ok(Response::Err(e)) => Err(NfsTryError::Other(anyhow!(e.error))),\n            Err(e) => Err(NfsTryError::Other(e)),\n        }\n    }\n\n    pub fn cancel_worktree_create(&self, worktree_id: &str) -> Result<(), anyhow::Error> {\n        if !self.ping() {\n            anyhow::bail!(\"grove daemon unreachable\");\n        }\n        let req = Request::CancelWorktreeCreate {\n            v: PROTOCOL_VERSION,\n            worktree_id: worktree_id.to_owned(),\n        };\n        match self.call(&req, REMOVE_RPC_TIMEOUT) {\n            Ok(Response::Ok(_)) => Ok(()),\n            Ok(Response::Err(e)) => Err(anyhow!(e.error)),\n            Err(e) => Err(e),\n        }\n    }\n\n    pub fn cleanup_worktree_create(&self, worktree_id: &str) -> Result<(), anyhow::Error> {\n        if !self.ping() {\n            anyhow::bail!(\"grove daemon unreachable\");\n        }\n        let req = Request::CleanupWorktreeCreate {\n            v: PROTOCOL_VERSION,","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-fast-worktree/src/nfs/client.rs#L219-L255","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: cancel immediately, bail on first unreachable daemon\nclient.cancel_worktree_create(&worktree_id)?;\n// after: retry briefly before giving up\nfor _ in 0..5 {\n    match client.cancel_worktree_create(&worktree_id) {\n        Ok(()) => break,\n        Err(e) if e.to_string().contains(\"grove daemon unreachable\") => std::thread::sleep(Duration::from_millis(500)),\n        Err(e) => return Err(e),\n    }\n}","handlingStrategy":"retry","validationCode":"fn daemon_reachable(client: &NfsWorktreeClient) -> bool { client.ping() }","typeGuard":null,"tryCatchPattern":"retry_with_backoff(5, Duration::from_millis(500), || {\n    client.cancel_worktree_create(&worktree_id)\n}).map_err(|e| e.context(\"grove daemon unreachable; cancel not delivered\"))?;","preventionTips":["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."],"tags":["network","ipc","daemon-unreachable","rust"],"backgroundTag":"daemon-unreachable","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}