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

unexpected response for ReloadCapsules

Error message

unexpected response for ReloadCapsules: {other:?}

What it means

The gateway requested a capsule reload from the kernel and expected KernelResponse::Success(_) or Error, but received a different variant. The gateway treats this as an internal protocol violation and surfaces it as GatewayError::Internal including the unexpected variant in the message.

Solutions

  1. Read the {other:?} variant in the message to identify the mismatched response
  2. Rebuild and redeploy the gateway and kernel together so their KernelResponse enums agree
  3. Confirm the kernel's ReloadCapsules handler returns KernelResponse::Success or KernelResponse::Error
  4. Audit BusKernelClient request-id/reply matching if responses from other requests leak in

Example fix

// before: stale gateway binary against updated kernel
// after: redeploy both from the same build
systemctl restart astrid-gateway astrid-daemon
Defensive patterns

Strategy: try-catch

Validate before calling

match kernel_response {
    KernelResponse::Success(_) | KernelResponse::Error(_) => Ok(()),
    other => Err(format!("kernel version mismatch: got {other:?} for ReloadCapsules")),
}

Type guard

fn is_success(resp: &KernelResponse) -> bool {
    matches!(resp, KernelResponse::Success(_))
}

Try / catch

match client.request(KernelRequest::ReloadCapsules).await? {
    KernelResponse::Success(_) => Ok(StatusCode::NO_CONTENT),
    KernelResponse::Error(msg) => Err(GatewayError::Forbidden { reason: msg }),
    other => { log::error!("kernel protocol mismatch: {other:?}"); Err(GatewayError::Internal(anyhow::anyhow!("unexpected response for ReloadCapsules: {other:?}"))) }
}

Prevention

When it happens

Trigger: reload_capsules() in crates/astrid-gateway/src/routes/system.rs sends KernelRequest::ReloadCapsules and matches only Success(_) and Error(msg); any other KernelResponse variant (e.g. AgentReadiness, CapsuleMetadata) reaches the catch-all arm.

Common situations: Kernel and gateway binaries at different versions after a partial deploy; the kernel handler for ReloadCapsules was changed to return a richer response type; bus reply correlation is misrouting a response from another in-flight request.

Related errors


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

Appendix: source

Thrown at crates/astrid-gateway/src/routes/system.rs:101

        (status = 204, description = "Capsules reloaded."),
        (status = 401, body = ErrorBody),
        (status = 403, body = ErrorBody, description = "Caller lacks `capsule:reload`."),
    )
)]
pub async fn reload_capsules(
    State(state): State<Arc<GatewayState>>,
    req: Request<axum::body::Body>,
) -> GatewayResult<StatusCode> {
    let caller = caller_from(&req)?.clone();
    let client = state.kernel_client_for(&caller)?;
    let resp = client
        .request(KernelRequest::ReloadCapsules)
        .await
        .map_err(daemon_kernel_error)?;
    match resp {
        KernelResponse::Success(_) => Ok(StatusCode::NO_CONTENT),
        KernelResponse::Error(msg) => Err(GatewayError::Forbidden { reason: msg }),
        other => Err(GatewayError::Internal(anyhow::anyhow!(
            "unexpected response for ReloadCapsules: {other:?}"
        ))),
    }
}

View on GitHub (pinned to affd8760f4)