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

gateway has no live capsule provider probe

Error message

gateway has no live capsule provider probe

What it means

This GatewayError::Internal is thrown by `provider_source_ids` when `state.topic_probe` is `None`, meaning the gateway process never had (or no longer has) a live capsule provider probe wired into its state. Without the probe the gateway cannot discover which loaded capsule serves registry requests, so the models/registry routes cannot proceed. It indicates a gateway startup/wiring problem, not a client mistake.

Source

Thrown at crates/astrid-gateway/src/routes/models.rs:335

        if probe.is_subscribed(&key).await {
            return Ok(());
        }
        if started.elapsed() >= timeout {
            return Err(GatewayError::Internal(anyhow::anyhow!(
                "no loaded capsule handles the registry request for caller"
            )));
        }
        tokio::time::sleep(CAPSULE_PROBE_INTERVAL).await;
    }
}

async fn provider_source_ids(
    state: &GatewayState,
    principal: &PrincipalId,
    request_topic: &str,
) -> GatewayResult<Vec<Uuid>> {
    let probe = state.topic_probe.as_ref().ok_or_else(|| {
        GatewayError::Internal(anyhow::anyhow!(
            "gateway has no live capsule provider probe"
        ))
    })?;
    let key = scoped_topic_probe_key(principal, request_topic);
    if !probe.is_subscribed(&key).await && !probe.ensure_subscribed(&key).await {
        return Err(GatewayError::Internal(anyhow::anyhow!(
            "no loaded capsule handles the registry request for caller"
        )));
    }
    let source_ids = probe.subscriber_source_ids(&key).await;
    if source_ids.is_empty() {
        return Err(GatewayError::Internal(anyhow::anyhow!(
            "no unique compatible loaded capsule handles the registry request for caller"
        )));
    }
    Ok(source_ids)
}

View on GitHub (pinned to affd8760f4)

Solutions

  1. Restart the gateway with its normal bootstrap so `GatewayState.topic_probe` is populated before serving traffic.
  2. Check gateway initialization/startup code for a path that constructs GatewayState without installing the topic probe; make probe installation mandatory and fail fast if absent.
  3. Verify the kernel/capsule runtime the probe depends on is available and healthy; fix the underlying init failure rather than letting the gateway run probe-less.
  4. If this appears only in tests, build the test GatewayState with a CapsuleTopicProbe instance (as the models.rs tests do).

Example fix

// before
let state = GatewayState { /* ... */ topic_probe: None };
// after
let state = GatewayState { /* ... */ topic_probe: Some(Arc::new(CapsuleTopicProbe::new(event_bus))) };
Defensive patterns

Strategy: fallback

Validate before calling

if gateway_state.topic_probe.is_none() {
    return Err(anyhow!("gateway not initialized with a capsule provider probe; refusing registry request"));
}

Type guard

fn has_topic_probe(state: &GatewayState) -> bool {
    state.topic_probe.is_some()
}

Try / catch

match registry_round_trip(&state, /* ... */).await {
    Err(e) if e.to_string().contains("no live capsule provider probe") => {
        // gateway misconfigured; fail fast / restart, do not retry the request
        return StatusCode::SERVICE_UNAVAILABLE;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Any registry route that calls `registry_round_trip` -> `provider_source_ids` (GET /api/models, GET/PUT /api/models/active) while `GatewayState.topic_probe` is None — e.g. the probe handle was never installed at gateway construction or was replaced/removed after startup.

Common situations: Gateway started in a mode or test harness that does not attach a topic probe; a bootstrap change where probe initialization failed and the gateway kept running without it; partially initialized state after a failed event-bus connect.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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