astrid-runtime/astrid · error · GatewayError::Internal
no loaded capsule handles the registry request for caller
Error message
no loaded capsule handles the registry request for caller
What it means
`ensure_registry_request_subscribed` polls the capsule probe until a loaded capsule is subscribed to the caller's registry request topic. If the probe still reports no subscription after the configured timeout, it returns `GatewayError::Internal('no loaded capsule handles the registry request for caller')`. The model registry request can therefore never be answered for this caller.
Source
Thrown at crates/astrid-gateway/src/routes/models.rs:321
) -> GatewayResult<()> {
let Some(probe) = &state.topic_probe else {
return Err(GatewayError::Kernel(
"gateway has no live capsule provider probe".into(),
));
};
let key = scoped_topic_probe_key(principal, request_topic);
if probe.is_subscribed(&key).await || probe.ensure_subscribed(&key).await {
return Ok(());
}
let timeout = state.registry_timeout.unwrap_or(REGISTRY_TIMEOUT);
let started = tokio::time::Instant::now();
loop {
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);View on GitHub (pinned to affd8760f4)
Solutions
- Check gateway startup logs for registry capsule load failures and reload the capsule.
- Increase the probe timeout if the capsule legitimately takes longer to subscribe than the current budget.
- Verify the subscription key derivation for the caller (principal/topic mapping) matches what the capsule subscribes to.
- Confirm the capsule process is healthy and re-probe; restart the gateway if the capsule manager is wedged.
Example fix
// before
if started.elapsed() >= timeout {
return Err(GatewayError::Internal(anyhow::anyhow!(
"no loaded capsule handles the registry request for caller"
)));
}
// after
if started.elapsed() >= timeout {
tracing::error!(%principal, %request_topic, ?timeout, "registry capsule never subscribed");
return Err(GatewayError::ServiceUnavailable(
"model registry capsule is not available".into(),
));
} Defensive patterns
Strategy: validation
Validate before calling
// before calling registry endpoints, check capsule readiness
if !probe.is_subscribed(®istry_request_key(principal, request_topic)).await {
return Err(ServiceUnavailable("registry capsule not ready"));
} Type guard
fn capsule_ready(probe: &CapsuleProbe, key: &str) -> bool {
// sync peek with a very short poll to avoid the full timeout path
probe.try_subscribed(key)
} Try / catch
match list_models(&state, caller).await {
Err(e) if e.message().contains("no loaded capsule handles the registry request") => {
tracing::error!("registry capsule missing/not subscribed");
StatusCode::SERVICE_UNAVAILABLE
}
r => r,
} Prevention
- Gate model routes on a startup health check that the registry capsule loaded and subscribed.
- Size the probe timeout above the capsule's worst-case warm-up time.
- Fail fast and log loudly at capsule load failure instead of silently continuing.
- Verify per-caller subscription key derivation against the capsule's own key computation in tests.
When it happens
Trigger: Calling any model registry endpoint when, after polling for `timeout` at `CAPSULE_PROBE_INTERVAL` intervals, no capsule is subscribed to the request topic key for the caller's principal — the registry capsule is missing, still loading, or subscribed under a different key.
Common situations: Registry capsule failed to load at gateway startup; capsule still warming up and the probe timeout is too short; per-caller subscription keys not established because the caller's identity/capsule mapping is wrong; capsule crashed after startup.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- registry did not respond
- durable capsule {id} conflicts with legacy native content
- durable capsule {id} failed byte-for-byte readback
- timed out waiting for capsule command result
- candidate generation for '{id}' did not activate within {}ms
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/8117259a3ee5b510.
Report an issue: GitHub.