astrid-runtime/astrid · error · GatewayError::Internal

gateway is not wired to a live event bus; session threads un

Error message

gateway is not wired to a live event bus; session threads unavailable

What it means

`require_bus` in `sessions.rs` pulls the live `EventBus` out of `GatewayState` and fails with a 500 `GatewayError::Internal` when `state.event_bus` is `None`, mirroring the behavior of `agent.rs`. Session routes need the bus to read/write session threads, so a gateway not co-located with a daemon cannot serve them. This is a deployment/wiring condition, not a client error.

Source

Thrown at crates/astrid-gateway/src/routes/sessions.rs:722

        &response_topic,
        payload,
        &correlation_id,
        &caller.principal,
        caller.device_key_id.as_deref(),
        &expected_sources,
        CAPSULE_TIMEOUT,
    )
    .await?;

    let parsed = parse_search_response(value)?;
    Ok(Json(parsed))
}

/// Pull the live event bus out of state, or fail with a 500 the same
/// way `agent.rs` does when the gateway isn't co-located with a daemon.
fn require_bus(state: &GatewayState) -> GatewayResult<Arc<EventBus>> {
    state.event_bus.clone().ok_or_else(|| {
        GatewayError::Internal(anyhow::anyhow!(
            "gateway is not wired to a live event bus; session threads unavailable"
        ))
    })
}

/// Gate the list route on the session `list` capability being present in the
/// caller principal's loaded capsule view, so a mixed 1.0/1.1 fleet behaves
/// honestly: a pre-1.1 session capsule yields `NotImplemented` (501) on the
/// 1.1 thread-management routes (`list` / `get_meta` / `update` / `delete` /
/// `search`) instead of waiting out the bus timeout on a verb nobody handles.
/// It probes the `list` verb specifically as a proxy — the whole 1.1 verb set
/// ships in one capsule, so a `list` handler implies all of them.
///
/// Uses the in-process [`CapsuleTopicProbe`] — a cap-free read of the live
/// registry, the same approach `POST /api/agent/prompt` takes for its
/// fail-fast. The check is principal-scoped because default is not a shared
/// fallback: a loaded default session capsule says nothing about whether the
/// caller's own runtime has finished async warm-up. The probe is required so

View on GitHub (pinned to affd8760f4)

Solutions

  1. Start/co-locate the astrid daemon so the gateway's `event_bus` is populated at startup.
  2. Verify gateway startup config actually wires the event bus (check startup logs for bus initialization).
  3. Route session-thread traffic to a gateway instance that is daemon-connected.
  4. If standalone operation is intended, hide/disable the session routes rather than serving 500s.
Defensive patterns

Strategy: validation

Validate before calling

// before calling any /sessions route, confirm the gateway has a bus
let has_bus = gateway_state.event_bus.is_some();
if !has_bus { return Err("gateway has no event bus; session routes unavailable".into()); }

Try / catch

match sessions.list().await {
    Ok(page) => page,
    Err(e) if e.message.contains("not wired to a live event bus") => {
        // deployment issue: reroute to daemon-connected gateway or surface clear error
        Err(SessionUnavailable)
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Any session route (`list_sessions_inner`, `get_session_messages_inner`, `get_session_inner`, `update_session_inner`, `delete_session_inner`, `search_sessions_inner`) calls `require_bus(state)` while `state.event_bus` is `None` — i.e. the gateway was started without a daemon/event-bus connection.

Common situations: Running the gateway standalone (no co-located daemon) and then hitting /sessions endpoints; the event bus failed to initialize at startup so `event_bus` stayed `None`; configuration that disables daemon wiring in an environment where session APIs are still used.

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/666557636ec7ba05. Report an issue: GitHub.