astrid-runtime/astrid · error · GatewayError::Internal
gateway is not wired to a live event bus; audit stream unava
Error message
gateway is not wired to a live event bus; audit stream unavailable
What it means
get_events streams audit events from the event bus; if the GatewayState has no event bus handle (the standalone constructor used in route-level tests), the route returns a 502-style Internal error immediately instead of hanging. This is an honest failure so dashboards don't wait forever on a stream that can never produce events.
Source
Thrown at crates/astrid-gateway/src/routes/events.rs:97
)
)]
pub async fn get_events(
State(state): State<Arc<GatewayState>>,
req: Request<axum::body::Body>,
) -> GatewayResult<Sse<impl Stream<Item = Result<Event, Infallible>>>> {
let caller = caller_from(&req)?.clone();
let capability_probe = req
.extensions()
.get::<CapabilityProbe>()
.cloned()
.unwrap_or_else(CapabilityProbe::deny_all);
// Without a bus handle (the standalone GatewayState ctor used
// by route-level tests), report an honest 502 instead of
// hanging — a dashboard would otherwise wait forever on a
// stream that can never produce.
let Some(bus) = state.event_bus.clone() else {
return Err(GatewayError::Internal(anyhow::anyhow!(
"gateway is not wired to a live event bus; audit stream unavailable"
)));
};
// The kernel-owned probe applies the caller's live device scope.
let initial_firehose = caller_holds(
&capability_probe,
&caller.principal,
caller.device_key_id.as_deref(),
AUDIT_FIREHOSE_CAP,
);
// Routed subscription so the audit firehose gets the same
// per-(topic, principal) DRR fairness the rest of the gateway
// SSE streams now use (#813 Layer 4). The principal-firehose
// filter at the post-receive layer is unchanged — it's a
// capability gate, not a routing concern.
let receiver = bus.subscribe_topic_routed(View on GitHub (pinned to affd8760f4)
Solutions
- Wire a live event bus handle into GatewayState before serving requests (state.event_bus = Some(bus))
- If this is a route-level test, use the full state constructor that includes the bus, or assert on the 502 behavior
- In production, add a startup check that fails fast when the bus is missing
Example fix
// before
let Some(bus) = state.event_bus.clone() else {
return Err(GatewayError::Internal(anyhow::anyhow!(
"gateway is not wired to a live event bus; audit stream unavailable"
)));
};
// after
let bus = state.event_bus.clone().ok_or_else(|| {
tracing::error!("event bus not configured; cannot serve audit stream");
GatewayError::Internal(anyhow::anyhow!(
"gateway is not wired to a live event bus; audit stream unavailable"
))
})?; Defensive patterns
Strategy: try-catch
Validate before calling
// Guard before opening the stream
if state.event_bus.is_none() {
return Err(StatusCode::SERVICE_UNAVAILABLE);
} Type guard
fn has_event_bus(state: &GatewayState) -> bool {
state.event_bus.is_some()
} Try / catch
match get_events(state, caller).await {
Ok(stream) => sse_response(stream),
Err(GatewayError::Internal(e)) if e.to_string().contains("not wired to a live event bus") => {
// 502: bus unavailable, do not retry against this instance
service_unavailable("audit stream unavailable")
}
Err(e) => internal_error(e),
} Prevention
- Always construct GatewayState via the full assembler that wires the event bus
- Add a startup assertion that event_bus is Some in production builds
- Keep a dashboard-side timeout/reconnect policy for SSE streams
When it happens
Trigger: Calling the /events SSE endpoint against a GatewayState built without wiring an event bus (e.g. in tests using the standalone GatewayState constructor, or a deployment where the bus handle was never attached).
Common situations: Integration tests constructing GatewayState manually; a misconfigured deployment that skipped bus initialization; refactoring that dropped the bus from state assembly.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- gateway is not wired to a live event bus; agent approval una
- gateway is not wired to a live event bus; live feed unavaila
- gateway is not wired to a live event bus; agent invocation u
- gateway is not wired to a live event bus; agent request stre
- gateway is not wired to a live audit log; historical-query u
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/717fc4c00f1b22ca.
Report an issue: GitHub.