astrid-runtime/astrid · error

shutdown stage gateway.process_reap: authenticated gateway…

Error message

shutdown stage gateway.process_reap: authenticated gateway PID {} did not exit

What it means

Graceful-shutdown timeout in stop_ready_gateway: the stop control request was acknowledged, but the authenticated gateway PID did not exit within the GRACE period. The stage label gateway.process_reap marks that reaping failed; the process may be stuck ignoring SIGTERM-style control, and the caller must treat the gateway as still running.

Solutions

  1. Wait a few seconds and check whether the PID exits on its own, then retry the stop
  2. Send SIGTERM/SIGKILL to the PID directly and clean up the socket and readiness files
  3. Inspect gateway logs for shutdown hangs (e.g. stuck request handlers) blocking exit
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at crates/astrid-cli/src/commands/mcp/lifecycle.rs:589 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


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

Appendix: source

Thrown at crates/astrid-cli/src/commands/mcp/lifecycle.rs:589

            );
        },
        astrid_core::local_transport::ConnectOutcome::Absent
        | astrid_core::local_transport::ConnectOutcome::Stale => {
            remove_dead_gateway_markers(&record).await?;
            return Ok(());
        },
    };

    request_gateway_control(stream, &record, GatewayControlOperation::Stop)
        .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 {

View on GitHub (pinned to affd8760f4)