astrid-runtime/astrid · error
gateway.idle_shutdown_secs must be positive and representabl
Error message
gateway.idle_shutdown_secs must be positive and representable
What it means
run() validates the configured gateway.idle_shutdown_secs before starting the gateway. The value must be strictly positive (zero disables the idle-shutdown grace in an invalid way here) and must fit into an Instant offset (checked_add must not overflow). Otherwise the gateway refuses to start with this bail.
Source
Thrown at crates/astrid-cli/src/commands/mcp/gateway.rs:478
boot_token: boot_token.clone(),
armed: true,
};
// The gateway's authenticated uplinks keep an automatically started daemon
// alive. Releasing them after the final host disconnects lets it retire.
// An existing operator-started daemon retains its chosen lifetime.
crate::commands::daemon::ensure_daemon("mcp-gateway")
.await
.context("failed to ensure Astrid daemon for MCP gateway")?;
let idle_grace = Duration::from_secs(
astrid_config::Config::load(Some(&daemon_root))?
.config
.gateway
.idle_shutdown_secs,
);
if idle_grace.is_zero() || Instant::now().checked_add(idle_grace).is_none() {
anyhow::bail!("gateway.idle_shutdown_secs must be positive and representable");
}
let hook_token = mint_hook_token();
let state = Arc::new(GatewayState::new(
daemon_root,
caller.clone(),
hook_token.clone(),
));
// Warm the authenticated principal selected by `ready`/`gateway` before
// accepting any attach registration. The lease was published first so this
// slow, pre-listener generation remains authenticated-stop capable.
state.client_for(&caller).await?;
let socket_path = prepare_gateway_socket(&lifecycle).await?;
let listener = UnixListener::bind(&socket_path)
.with_context(|| format!("failed to bind MCP gateway at {}", socket_path.display()))?;
set_socket_mode(&socket_path)?;
let ready = GatewayReady {
version: 1,View on GitHub (pinned to affd8760f4)
Solutions
- Set gateway.idle_shutdown_secs in your astrid config to a positive value (e.g. 30 or 60).
- Do not use 0 to disable idle shutdown; use the config mechanism intended for disabling it, or a large-but-representable duration.
- Clamp the configured value in code/config to a sane range such as 1..=86400 before launching the gateway.
- Reload/re-verify the config after edits: astrid_config::Config::load(Some(&daemon_root)) picks up the file at daemon_root.
Example fix
// before (config) [gateway] idle_shutdown_secs = 0 // after [gateway] idle_shutdown_secs = 60
Defensive patterns
Strategy: validation
Validate before calling
fn valid_idle_secs(v: i64) -> bool { v > 0 && v <= 86_400 } Type guard
fn as_positive_secs(raw: &str) -> Option<u64> {
raw.trim().parse::<u64>().ok().filter(|&s| s > 0)
} Try / catch
match result {
Err(e) if e.to_string().contains("idle_shutdown_secs") => eprintln!("fix [gateway].idle_shutdown_secs in your astrid config: must be > 0"),
other => other?,
} Prevention
- Never set idle_shutdown_secs to 0 expecting 'disabled'.
- Clamp config values to 1..=86400 in tooling that generates the config.
- Validate the config file after hand edits before launching the gateway.
- Keep durations in one unit (seconds) to avoid magnitude mistakes.
When it happens
Trigger: Setting gateway.idle_shutdown_secs to 0, to a negative value, or to a magnitude so large that Instant::now() + idle_grace overflows when loading astrid_config::Config in `run`.
Common situations: Typo or misunderstanding in the config file (e.g. idle_shutdown_secs: 0 thinking it means 'never idle-shutdown'); hand-editing the config with an absurdly large number of seconds; generating the config programmatically with an out-of-range integer.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- {e}
- invalid value for {capsule_id}.{key}: expected one of {}, go
- signed Distro member '{}' must resolve to a prebuilt .capsul
- MCP attach host is empty
- MCP gateway control authority is incomplete
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/f13f84be358de3e6.
Report an issue: GitHub.