astrid-runtime/astrid · error · anyhow::Error

bus admin request timed out after {:?} waiting for {want_res

Error message

bus admin request timed out after {:?} waiting for {want_response}

What it means

BusAdminClient::request publishes an admin request onto the internal event bus and waits for the matching response topic. If the deadline (self.timeout, overridable via with_timeout) elapses before a response event arrives, it returns this anyhow error naming the timeout and the response topic it was waiting on. It means the kernel handler never answered (or answered too slowly) for that admin operation.

Source

Thrown at crates/astrid-gateway/src/bus_admin.rs:149

        // bearer's key_id rides on every admin op so a paired device cannot
        // exceed its scope (e.g. a use-only device's PairDeviceIssue is denied
        // even though its principal holds `self:auth:pair`).
        if let Some(key_id) = &self.device_key_id {
            msg = msg.with_device_key_id(key_id.clone());
        }
        self.bus.publish(AstridEvent::Ipc {
            metadata: EventMetadata::new("astrid-gateway::bus_admin"),
            message: msg,
        });

        let deadline = tokio::time::Instant::now()
            .checked_add(self.timeout)
            .unwrap_or_else(tokio::time::Instant::now);

        loop {
            let remaining = deadline.saturating_duration_since(tokio::time::Instant::now());
            if remaining.is_zero() {
                return Err(anyhow!(
                    "bus admin request timed out after {:?} waiting for {want_response}",
                    self.timeout
                ));
            }
            let event = match tokio::time::timeout(remaining, receiver.recv()).await {
                Ok(Some(ev)) => ev,
                Ok(None) => {
                    return Err(anyhow!(
                        "event bus closed before response on {want_response}"
                    ));
                },
                Err(_) => {
                    return Err(anyhow!(
                        "bus admin request timed out after {:?} waiting for {want_response}",
                        self.timeout
                    ));
                },
            };

View on GitHub (pinned to affd8760f4)

Solutions

  1. Verify the kernel/admin dispatcher is running and subscribed to the request topic
  2. Increase the timeout via BusAdminClient::with_timeout for slow admin operations
  3. Check kernel logs for errors or panics in the handler for that AdminRequestKind
  4. Confirm the handler publishes its response on response_topic(&kind) with the matching request_id

Example fix

// before
let client = BusAdminClient::new(&bus, caller);
let resp = client.request(AdminRequestKind::ListDevices).await?;
// after
let client = BusAdminClient::new(&bus, caller).with_timeout(std::time::Duration::from_secs(30));
let resp = client.request(AdminRequestKind::ListDevices).await?;
Defensive patterns

Strategy: retry

Validate before calling

// Before issuing, sanity-check the client timeout budget:
fn has_adequate_timeout(c: &BusAdminClient, min: std::time::Duration) -> bool { /* compare configured timeout >= min via with_timeout construction */ true }

Try / catch

match client.request(kind).await {
    Ok(resp) => resp,
    Err(e) if e.to_string().contains("timed out") => {
        // check kernel liveness, optionally retry with backoff and a larger timeout
        retry_with_backoff(kind).await
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling BusAdminClient::request(kind) when the kernel-side handler for that AdminRequestKind is not running, is blocked, or takes longer than self.timeout; also when remaining is already zero on loop entry because the deadline passed before the first recv.

Common situations: Kernel service not started or crashed while gateway is up; timeout set too low (default too aggressive for slow ops like migration-heavy admin calls); event bus backpressure dropping or delaying the response publish; wrong request topic/response topic pairing after a refactor.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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