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
- Read the {other:?} variant in the message to identify the mismatched response
- Rebuild and redeploy the gateway and kernel together so their KernelResponse enums agree
- Confirm the kernel's ReloadCapsules handler returns KernelResponse::Success or KernelResponse::Error
- 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
- Keep gateway and daemon-kernel on identical versions and redeploy them together
- Add exhaustive match arms (deny unknown variants) so compile-time checks catch enum drift
- Cover ReloadCapsules with a gateway-to-kernel integration test
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
- unexpected response for GetAgentReadiness
- unexpected daemon metadata response
- unexpected distro lock response
- unexpected response while resolving principal UID
- daemon did not return an agent-readiness response
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)