astrid-runtime/astrid · error

Admin request timed out after {:?} waiting for {want_respons

Error message

Admin request timed out after {:?} waiting for {want_response}

What it means

send_and_wait sends an admin request to the daemon and loops reading frames until a wanted response arrives, with a self.timeout deadline computed up front. If the whole budget is consumed before the matching response frame is seen, it bails naming the expected response type. This distinguishes 'daemon alive but slow/unresponsive' from connection errors.

Source

Thrown at crates/astrid-uplink/src/admin_client.rs:181

    async fn send_and_wait(
        &mut self,
        topic: Topic,
        want_response: Topic,
        request_id: String,
        payload: Value,
    ) -> Result<AdminResponseBody> {
        let msg = IpcMessage::new(topic, IpcPayload::RawJson(payload), Uuid::nil())
            .with_principal(self.caller.to_string());
        self.inner.send_message(msg).await?;

        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() {
                anyhow::bail!(
                    "Admin request timed out after {:?} waiting for {want_response}",
                    self.timeout
                );
            }
            let read = tokio::time::timeout(remaining, self.inner.read_raw_frame()).await;
            let frame = match read {
                Ok(Ok(Some(bytes))) => bytes,
                Ok(Ok(None)) => {
                    anyhow::bail!("Daemon closed the connection before responding");
                },
                Ok(Err(e)) => return Err(e),
                Err(_) => {
                    anyhow::bail!(
                        "Admin request timed out after {:?} waiting for {want_response}",
                        self.timeout
                    );
                },
            };

View on GitHub (pinned to affd8760f4)

Solutions

  1. Increase the AdminClient timeout to comfortably exceed the daemon's worst-case handling time for the operation.
  2. Check the daemon's logs/health to confirm it is processing admin requests and not wedged; restart it if hung.
  3. Retry the request with backoff once the daemon is responsive again — the request may not have been processed.
  4. Verify the daemon version supports the requested operation (an unsupported request may silently get no reply).

Example fix

// before
classic let client = AdminClient::with_timeout(Duration::from_secs(5));
// after
let client = AdminClient::with_timeout(Duration::from_secs(60));
Defensive patterns

Strategy: retry

Validate before calling

// Pre-check daemon responsiveness with a cheap call before expensive requests
admin_client.request(HealthCheck {}).await?; // fails fast if daemon unresponsive

Try / catch

match admin_client.request(req).await {
    Ok(resp) => resp,
    Err(e) if e.to_string().contains("Admin request timed out") => {
        tokio::time::sleep(Duration::from_secs(2)).await;
        admin_client.request(req).await? // bounded retry
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling AdminClient::request or request_agent_derive when the daemon takes longer than self.timeout to produce the wanted response — e.g. daemon busy with a long operation, response never sent, or timeout configured too small for the operation.

Common situations: Daemon under heavy load (large sync/derive operations) exceeding the client timeout; a daemon bug drops the reply for that request type; client constructed with a very short timeout for an inherently slow admin operation.

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/321a5f3dd88295e7. Report an issue: GitHub.