{"record":{"id":"bfff3ad58c07bd3f","repo":"astrid-runtime/astrid","slug":"shutdown-stage-gateway-startup-identity-lease-has","errorCode":null,"errorMessage":"shutdown stage gateway.startup_identity: lease has no gateway PID","messagePattern":"shutdown stage gateway\\.startup_identity: lease has no gateway PID","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/mcp/lifecycle.rs","lineNumber":599,"sourceCode":"        .await\n        .context(\"shutdown stage gateway.final_ack\")?;\n    if !crate::commands::daemon_control::wait_for_exit(\n        record.pid,\n        crate::commands::daemon_control::GRACE,\n    )\n    .await\n    {\n        anyhow::bail!(\n            \"shutdown stage gateway.process_reap: authenticated gateway PID {} did not exit\",\n            record.pid\n        );\n    }\n    remove_dead_gateway_markers(&record).await\n}\n\nasync fn stop_startup_gateway(lease: &GatewayStartupLease) -> Result<()> {\n    let Some(gateway_pid) = lease.gateway_pid else {\n        anyhow::bail!(\"shutdown stage gateway.startup_identity: lease has no gateway PID\");\n    };\n    let Some(gateway_exe) = lease.gateway_exe.as_deref() else {\n        anyhow::bail!(\"shutdown stage gateway.startup_identity: lease has no executable\");\n    };\n    let current = read_gateway_startup_lease()?.ok_or_else(|| {\n        anyhow::anyhow!(\"shutdown stage gateway.startup_identity: lease disappeared\")\n    })?;\n    if current != *lease {\n        anyhow::bail!(\"shutdown stage gateway.startup_identity: startup generation changed\");\n    }\n\n    let outcome =\n        crate::commands::daemon_control::terminate_known(gateway_pid, Some(gateway_exe)).await;\n    if !matches!(\n        outcome,\n        crate::commands::daemon_control::KillOutcome::TermExited\n            | crate::commands::daemon_control::KillOutcome::KilledExited\n    ) {","sourceCodeStart":581,"sourceCodeEnd":617,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/mcp/lifecycle.rs#L581-L617","documentation":"Thrown by stop_startup_gateway during startup-gateway shutdown when the GatewayStartupLease has a None gateway_pid. The library refuses to act on a lease that doesn't identify which process it started, since killing the wrong process would be unsafe.","triggerScenarios":"Calling stop_gateway (directly or via shutdown paths) while the persisted gateway startup lease lacks a gateway_pid field — e.g. a partially written or corrupted lease file, or a lease created by an older version that didn't record the PID.","commonSituations":"Upgrading astrid from a version whose lease format omitted gateway_pid; a crash mid-write leaving a truncated lease file; hand-editing or deleting fields in the lease/state directory.","solutions":["Delete the stale gateway startup lease/state file so a fresh start can recreate a complete lease","Inspect the lease file to confirm gateway_pid is missing and re-run gateway startup to regenerate it","Check version compatibility: clear state written by an older astrid version before upgrading","File a bug if a fresh startup produced a lease without a gateway PID"],"exampleFix":"// before: acting on a possibly-incomplete lease\nstop_gateway().await?;\n// after: verify the lease is complete before stopping\nlet lease = read_gateway_startup_lease()?;\nif lease.map(|l| l.gateway_pid.is_some() && l.gateway_exe.is_some()) != Some(true) {\n    remove_gateway_startup_lease(None)?; // clear stale lease first\n}\nstop_gateway().await?;","handlingStrategy":"validation","validationCode":"let lease = read_gateway_startup_lease()?;\nanyhow::ensure!(\n    lease.as_ref().and_then(|l| l.gateway_pid).is_some(),\n    \"startup lease incomplete; restart gateway\"\n);","typeGuard":"fn has_gateway_pid(l: &Option<GatewayStartupLease>) -> bool {\n    l.as_ref().map(|l| l.gateway_pid.is_some()).unwrap_or(false)\n}","tryCatchPattern":"match stop_gateway().await {\n    Err(e) if e.to_string().contains(\"lease has no gateway PID\") => {\n        remove_gateway_startup_lease(None)?;\n    },\n    other => other?,\n}","preventionTips":["Never hand-edit gateway lease/state files","Clear state after upgrading astrid versions","Always start the gateway through the supported startup API so the lease is complete"],"tags":["process-management","state-corruption","shutdown"],"backgroundTag":"internal-invariant-violation","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}