Kuberwastaken/claurst · error

rmcp read_resource ' ' failed

Error message

rmcp read_resource '{}' failed: {}

What it means

Raised in `RmcpClientBackend::read_resource` when the rmcp peer's `read_resource` call for the given URI fails during the `resources/read` round-trip. This wraps transport failures and JSON-RPC error responses returned by the MCP server, such as the resource not existing, the URI being malformed, or the session being closed. The URI and the underlying rmcp error are included so the failing read can be identified.

Solutions

  1. Re-run list_resources and confirm the URI still exists on the server before reading.
  2. Check the inner error text: 'not found' means stale/wrong URI; 'method not found' means no resources capability.
  3. Fix the URI to match exactly what the server registered (scheme, host, path).
  4. Reconnect the session if the transport closed, then retry.

Example fix

// before: caching URIs forever
let contents = backend.read_resource(&cached_uri).await?;
// after: refresh the resource list when a read fails
let contents = match backend.read_resource(&cached_uri).await {
    Ok(c) => c,
    Err(_) => {
        let resources = backend.list_resources().await?;
        let fresh = resources.iter().find(|r| r.name == resource_name)
            .ok_or_else(|| anyhow::anyhow!("resource {resource_name} no longer exists"))?;
        backend.read_resource(&fresh.uri).await?
    }
};
Defensive patterns

Strategy: validation

Validate before calling

async fn ensure_resource_exists(backend: &dyn McpClientBackend, uri: &str) -> anyhow::Result<()> {
    let known = backend.list_resources().await?;
    anyhow::ensure!(known.iter().any(|r| r.uri == uri), "resource '{uri}' not offered by server");
    Ok(())
}

Try / catch

match backend.read_resource(uri).await {
    Ok(c) => c,
    Err(e) if e.to_string().contains("not found") => {
        eprintln!("resource {uri} no longer exists; refresh resource list");
        ResourceContents::default()
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `read_resource(uri)` when the request fails at protocol level: unknown or stale URI (server returns 'resource not found'), URI not matching the server's URI template, server lacks the resources capability, transport failure, or session closed mid-call.

Common situations: Reading a resource URI discovered in a previous session after the server restarted and its resource set changed; typo in the URI scheme the server registered; reading a resource whose underlying file/database was deleted; the server requires subscription or dynamic discovery before the URI is valid.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10). Data as JSON: /api/errors/87c2a97330c11f17. Report an issue: GitHub.

Appendix: source

Thrown at src-rust/crates/mcp/src/rmcp_backend.rs:543

            .map_err(|e| anyhow::anyhow!("rmcp call_tool '{}' failed: {}", name, e))?;
        Ok(convert_call_tool_result(result))
    }

    async fn list_resources(&self) -> anyhow::Result<Vec<McpResource>> {
        let resources = self
            .peer
            .list_all_resources()
            .await
            .map_err(|e| anyhow::anyhow!("rmcp list_resources failed: {}", e))?;
        Ok(resources.into_iter().map(convert_resource).collect())
    }

    async fn read_resource(&self, uri: &str) -> anyhow::Result<ResourceContents> {
        let result = self
            .peer
            .read_resource(rmcp_model::ReadResourceRequestParams::new(uri.to_string()))
            .await
            .map_err(|e| anyhow::anyhow!("rmcp read_resource '{}' failed: {}", uri, e))?;
        let first = result
            .contents
            .into_iter()
            .next()
            .ok_or_else(|| anyhow::anyhow!("rmcp read_resource '{}' returned no contents", uri))?;
        Ok(convert_resource_contents(first))
    }

    async fn list_prompts(&self) -> anyhow::Result<Vec<McpPrompt>> {
        let prompts = self
            .peer
            .list_all_prompts()
            .await
            .map_err(|e| anyhow::anyhow!("rmcp list_prompts failed: {}", e))?;
        Ok(prompts.into_iter().map(convert_prompt).collect())
    }

    async fn get_prompt(

View on GitHub (pinned to b0637c97ec)