astrid-runtime/astrid · error
shutdown stage gateway.startup_identity: lease has no gatewa
Error message
shutdown stage gateway.startup_identity: lease has no gateway PID
What it means
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.
Source
Thrown at crates/astrid-cli/src/commands/mcp/lifecycle.rs:599
.await
.context("shutdown stage gateway.final_ack")?;
if !crate::commands::daemon_control::wait_for_exit(
record.pid,
crate::commands::daemon_control::GRACE,
)
.await
{
anyhow::bail!(
"shutdown stage gateway.process_reap: authenticated gateway PID {} did not exit",
record.pid
);
}
remove_dead_gateway_markers(&record).await
}
async fn stop_startup_gateway(lease: &GatewayStartupLease) -> Result<()> {
let Some(gateway_pid) = lease.gateway_pid else {
anyhow::bail!("shutdown stage gateway.startup_identity: lease has no gateway PID");
};
let Some(gateway_exe) = lease.gateway_exe.as_deref() else {
anyhow::bail!("shutdown stage gateway.startup_identity: lease has no executable");
};
let current = read_gateway_startup_lease()?.ok_or_else(|| {
anyhow::anyhow!("shutdown stage gateway.startup_identity: lease disappeared")
})?;
if current != *lease {
anyhow::bail!("shutdown stage gateway.startup_identity: startup generation changed");
}
let outcome =
crate::commands::daemon_control::terminate_known(gateway_pid, Some(gateway_exe)).await;
if !matches!(
outcome,
crate::commands::daemon_control::KillOutcome::TermExited
| crate::commands::daemon_control::KillOutcome::KilledExited
) {View on GitHub (pinned to affd8760f4)
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
Example fix
// before: acting on a possibly-incomplete lease
stop_gateway().await?;
// after: verify the lease is complete before stopping
let lease = read_gateway_startup_lease()?;
if lease.map(|l| l.gateway_pid.is_some() && l.gateway_exe.is_some()) != Some(true) {
remove_gateway_startup_lease(None)?; // clear stale lease first
}
stop_gateway().await?; Defensive patterns
Strategy: validation
Validate before calling
let lease = read_gateway_startup_lease()?;
anyhow::ensure!(
lease.as_ref().and_then(|l| l.gateway_pid).is_some(),
"startup lease incomplete; restart gateway"
); Type guard
fn has_gateway_pid(l: &Option<GatewayStartupLease>) -> bool {
l.as_ref().map(|l| l.gateway_pid.is_some()).unwrap_or(false)
} Try / catch
match stop_gateway().await {
Err(e) if e.to_string().contains("lease has no gateway PID") => {
remove_gateway_startup_lease(None)?;
},
other => other?,
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- shutdown stage gateway.startup_identity: lease has no execut
- shutdown stage gateway.startup_reap: starting gateway PID {g
- {primary:#}; additional shutdown failure: {secondary:#}
- shutdown stage daemon.shutdown_ack: rejected: {reason}
- shutdown stage daemon.shutdown_ack: unexpected response: {ot
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/bfff3ad58c07bd3f.
Report an issue: GitHub.