{"record":{"id":"0805faa76278438b","repo":"astrid-runtime/astrid","slug":"an-astrid-daemon-appears-to-be-running-but-its-upl","errorCode":null,"errorMessage":"an Astrid daemon appears to be running but its uplink is unreachable                  (missing or unlinked system.sock while the PID/lock is live).                  run `astrid restart`","messagePattern":"an Astrid daemon appears to be running but its uplink is unreachable                  \\(missing or unlinked system\\.sock while the PID/lock is live\\)\\.                  run `astrid restart`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/daemon.rs","lineNumber":581,"sourceCode":"        },\n    }\n}\n\n/// Handle `astrid status`.\npub(crate) async fn handle_status(output_format: OutputFormat) -> Result<()> {\n    validate_runtime_admission()?;\n    let socket_path = socket_client::proxy_socket_path();\n    let endpoint_present = astrid_core::local_transport::endpoint_is_present(&socket_path)\n        .context(\"failed to inspect daemon endpoint\")\n        .unwrap_or(false);\n    let recorded_alive = recorded_daemon_pid_is_alive();\n    match decide_status_action(endpoint_present, recorded_alive) {\n        StatusAction::NotRunning => {\n            print_status(output_format, None)?;\n            return Ok(());\n        },\n        StatusAction::RunningButUnreachable => {\n            anyhow::bail!(\n                \"an Astrid daemon appears to be running but its uplink is unreachable                  (missing or unlinked system.sock while the PID/lock is live).                  run `astrid restart`\"\n            );\n        },\n        StatusAction::QueryLiveSocket => {},\n    }\n\n    let connect = tokio::time::timeout(\n        STATUS_CONNECT_TIMEOUT,\n        socket_client::connect_kernel_for_workspace(None),\n    )\n    .await;\n    let Ok(Ok(mut client)) = connect else {\n        if recorded_alive {\n            anyhow::bail!(\n                \"an Astrid daemon appears to be running but its uplink is unreachable; run `astrid restart`\"\n            );\n        }\n        print_status(output_format, None)?;","sourceCodeStart":563,"sourceCodeEnd":599,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/daemon.rs#L563-L599","documentation":"`astrid status` treats a live recorded PID/lock with a missing or unlinked system.sock as a daemon whose uplink is gone. Because the process is still alive but cannot be contacted, status cannot be answered, and `start` refuses to force-recycle (it must not kill a booting daemon or an innocent recycled PID). The CLI bails with an actionable message directing the user to `astrid restart`, which performs an identity-gated SIGTERM→SIGKILL and respawns cleanly.","triggerScenarios":"Running `astrid status` when decide_status_action returns RunningButUnreachable: the PID file/lock records a live daemon but endpoint_is_present(proxy_socket_path()) is false — the system.sock was deleted, never created, or unlinked (e.g. tmp cleaner removed it, daemon half-crashed, or stale run-dir).","commonSituations":"Systemd-tmpfiles or periodic /tmp cleanup deleting the socket; daemon process wedged after SIGSTOP or deadlock so it stopped serving the socket; a crashed daemon whose PID file survived; running the CLI in a different container/mount namespace than the daemon so the socket path differs.","solutions":["Run `astrid restart` — it identity-gates the recorded PID, SIGTERM/SIGKILLs it, cleans stale markers, and spawns a fresh daemon.","Inspect the run dir (socket_path/pid_path) to confirm system.sock is actually gone and whether the recorded PID belongs to astrid (ps -p <pid>).","If the PID was recycled by an unrelated process, remove the stale PID/lock files manually before starting.","Prevent socket loss by pointing the runtime dir at a location not swept by tmp cleaners."],"exampleFix":"// before (stale/unlinked socket with live PID)\n$ astrid status\nError: an Astrid daemon appears to be running but its uplink is unreachable ... run `astrid restart`\n// after\n$ astrid restart\n$ astrid status  # now reports the running daemon","handlingStrategy":"validation","validationCode":"// before scripting around status, check reachability\nlet endpoint_present = astrid_core::local_transport::endpoint_is_present(&socket_client::proxy_socket_path())?;\nlet pid_alive = /* read pid file and check /proc */;\nif pid_alive && !endpoint_present {\n    // skip status; go straight to `astrid restart`\n    run(vec![\"astrid\", \"restart\"])?;\n}","typeGuard":"fn daemon_is_reachable(endpoint_present: bool, recorded_alive: bool) -> bool {\n    // only trust status when the socket exists, not merely when a PID is live\n    endpoint_present && recorded_alive\n}","tryCatchPattern":"match astrid_status() {\n    Ok(status) => use(status),\n    Err(e) if e.to_string().contains(\"uplink is unreachable\") => run(vec![\"astrid\", \"restart\"])?,\n    Err(e) => return Err(e),\n}","preventionTips":["Point the runtime dir at a path not swept by tmp cleaners (avoid /tmp for system.sock).","Prefer `astrid restart` over kill -9 so markers are cleaned and identity-checked.","Monitor for the 'RunningButUnreachable' state rather than repeatedly polling status.","Pin AX_HOME consistently in shell profiles/scripts so CLI and daemon share one run-dir."],"tags":["daemon","socket","ipc","cli"],"backgroundTag":"connection-refused","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"}