{"record":{"id":"99675a083a56ef22","repo":"astrid-runtime/astrid","slug":"connection-timed-out-after-5s","errorCode":null,"errorMessage":"connection timed out after 5s","messagePattern":"connection timed out after 5s","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/doctor.rs","lineNumber":232,"sourceCode":"    println!(\n        \"  [{}]  {} — {}\",\n        \"WARN\".yellow().bold(),\n        name.bold(),\n        detail\n    );\n}\n\nfn check_fail(name: &str, detail: &str) {\n    println!(\"  [{}]  {} — {}\", \"FAIL\".red().bold(), name.bold(), detail);\n}\n\nasync fn daemon_roundtrip() -> Result<()> {\n    let mut client = tokio::time::timeout(\n        Duration::from_secs(5),\n        crate::socket_client::connect_kernel_for_workspace(None),\n    )\n    .await\n    .map_err(|_| anyhow::anyhow!(\"connection timed out after 5s\"))??;\n    match tokio::time::timeout(\n        Duration::from_secs(5),\n        client.request(KernelRequest::GetStatus),\n    )\n    .await\n    .map_err(|_| anyhow::anyhow!(\"daemon response timed out after 5s\"))??\n    {\n        KernelResponse::Status(_) => Ok(()),\n        KernelResponse::Error(message) => {\n            Err(anyhow::anyhow!(\"daemon rejected status request: {message}\"))\n        },\n        _ => Err(anyhow::anyhow!(\n            \"daemon returned an unexpected status response\"\n        )),\n    }\n}\n\n/// Query the daemon for agent-loop readiness over the same socket the","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/doctor.rs#L214-L250","documentation":"The doctor daemon_roundtrip check wraps connect_kernel_for_workspace in a 5-second tokio timeout. If connecting to the astrid kernel daemon's unix socket does not complete within 5s, the timeout elapses and this error is raised, independent of the underlying connect error (which is discarded by the map_err on the elapsed branch).","triggerScenarios":"`astrid doctor` (run -> daemon_roundtrip) when the kernel daemon is not running, the socket path is stale, the daemon is wedged and not accepting connections, or the system is so loaded the connect handshake exceeds 5s.","commonSituations":"Daemon crashed or was killed; machine asleep/resumed leaving a stale socket; running doctor in a container/WSL where the socket isn't shared; daemon startup still in progress.","solutions":["Start or restart the astrid daemon, then re-run `astrid doctor`.","Check the socket file exists at the expected workspace path and remove stale sockets.","Retry after machine wake-up or heavy load; if intermittent, investigate daemon responsiveness.","Look at daemon logs to see why it is not accepting connections."],"exampleFix":"// before: doctor fails with timeout\n$ astrid doctor\nError: connection timed out after 5s\n// after\n$ astrid daemon start && astrid doctor  # status: ok","handlingStrategy":"retry","validationCode":"// Pre-check the socket exists before attempting connect\nlet sock = astrid_socket_path(None)?;\nif !sock.exists() { eprintln!(\"daemon socket missing — is the daemon running?\"); }","typeGuard":null,"tryCatchPattern":"match daemon_roundtrip().await {\n    Err(e) if e.to_string().contains(\"connection timed out\") => {\n        // start the daemon, then retry once\n        start_daemon().await?;\n        daemon_roundtrip().await?;\n    },\n    other => other?,\n}","preventionTips":["Ensure the daemon is started (or auto-started) before doctor.","Remove stale sockets after machine sleep/resume.","Share the socket correctly when running inside containers/WSL.","Wrap daemon calls in a bounded retry with backoff."],"tags":["timeout","ipc","daemon","network"],"backgroundTag":"request-timeout","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}