Hmbown/CodeWhale · error

MCP exceeded its overall deadline

Error message

MCP {} exceeded its overall {:?} deadline

What it means

Catalog listing runs under an overall deadline; remaining_timeout computes how much time is left before each pagination request. If the deadline has already passed (remaining is zero), it fails loudly instead of issuing a call that would certainly be cut short.

Solutions

  1. Increase the overall_timeout budget for this MCP server
  2. Reduce catalog size limits (max_pages/max_items) so the deadline is not consumed
  3. Investigate why the server is slow (blocking on startup, slow disk, network tool calls)

Example fix

// before
McpCatalogBudget::new(method, Duration::from_secs(5), ...)
// after
McpCatalogBudget::new(method, Duration::from_secs(30), ...)
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling, ensure budget fits expected workload:
let pages_hint = 20;
assert!(overall_timeout > Duration::from_secs(pages_hint), "timeout too small for catalog size");

Try / catch

match client.list_resources_with_metadata().await {
    Ok(entries) => use(entries),
    Err(e) if e.to_string().contains("exceeded its overall") => {
        eprintln!("catalog listing timed out; raising budget or shrinking limits");
        // retry with a larger overall_timeout
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: list_paginated calls remaining_timeout after Instant::now() has passed the deadline established at the start of the operation (overall_timeout elapsed, or consumed by prior pages/parsing).

Common situations: Slow or hung MCP server over stdio; too many pages/items to fit the budget timeout; overall_timeout configured too small for a large catalog.

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 Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/3d2e3cfd0f559509. Report an issue: GitHub.

Appendix: source

Thrown at crates/mcp/src/stdio_client.rs:348

    fn with_limits(
        method: &str,
        timeout: Duration,
        max_pages: usize,
        max_items: usize,
        max_bytes: usize,
    ) -> Self {
        Self {
            max_pages,
            max_items,
            max_bytes,
            ..Self::new(method, timeout)
        }
    }

    fn remaining_timeout(&self) -> Result<Duration> {
        let remaining = self.deadline.saturating_duration_since(Instant::now());
        if remaining.is_zero() {
            bail!(
                "MCP {} exceeded its overall {:?} deadline",
                self.method,
                self.overall_timeout
            );
        }
        Ok(remaining)
    }

    fn observe_page(&mut self, page: &Value, field: &str) -> Result<Option<String>> {
        let values = page.get(field).and_then(Value::as_array).with_context(|| {
            format!(
                "MCP {} response did not contain a '{field}' array",
                self.method
            )
        })?;

        self.pages = self.pages.saturating_add(1);
        self.items = self.items.saturating_add(values.len());

View on GitHub (pinned to 73e0f67d83)