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

  1. Delete the stale gateway startup lease/state file so a fresh start can recreate a complete lease
  2. Inspect the lease file to confirm gateway_pid is missing and re-run gateway startup to regenerate it
  3. Check version compatibility: clear state written by an older astrid version before upgrading
  4. 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

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


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/bfff3ad58c07bd3f. Report an issue: GitHub.