astrid-runtime/astrid · error

MCP gateway did not become ready within

Error message

MCP gateway did not become ready within {} seconds

What it means

Fired by wait_for_gateway when, after cleaning unowned startup state and spawning a gateway child, the gateway still has not published readiness before the overall deadline. Spawn-and-wait has exhausted its retry budget.

Solutions

  1. Read gateway logs to find the startup failure
  2. Start the gateway manually to surface the error
  3. Check socket path permissions and stale startup state
Defensive patterns

Strategy: retry

When it happens

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

Common situations: See trigger scenarios.


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

Appendix: source

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

                if Instant::now() >= deadline {
                    anyhow::bail!(
                        "MCP gateway is starting but has not published readiness within {} seconds",
                        SPAWNED_READY_TIMEOUT.as_secs()
                    );
                }
                tokio::time::sleep(READY_POLL).await;
                continue;
            };
            clean_unowned_gateway_startup(&lifecycle)
                .await
                .context("shutdown stage gateway.startup_cleanup")?;
            spawn_gateway(principal)?;
            drop(lifecycle);
            drop(supervisor);
            spawned = true;
        }
        if Instant::now() >= deadline {
            anyhow::bail!(
                "MCP gateway did not become ready within {} seconds",
                SPAWNED_READY_TIMEOUT.as_secs()
            );
        }
        tokio::time::sleep(READY_POLL).await;
    }
}

/// Stop the persistent gateway through its owner-authenticated control path.
///
/// Success means the gateway returned its final teardown ACK, its recorded
/// process exited, the listener is absent, and the exact readiness record is
/// gone. Inconsistent or unowned state is left intact and reported.
pub(crate) async fn stop_gateway() -> Result<()> {
    let socket = gateway_socket_path()?;
    // A fresh or already-clean runtime has no gateway generation to lock.
    // Acquiring the lifecycle lock here would create the transient root before
    // admission, which is forbidden for the stopped durable layout.

View on GitHub (pinned to affd8760f4)