{"record":{"id":"87c2a97330c11f17","repo":"Kuberwastaken/claurst","slug":"rmcp-read-resource-failed","errorCode":null,"errorMessage":"rmcp read_resource '{}' failed: {}","messagePattern":"rmcp read_resource '(.+?)' failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-rust/crates/mcp/src/rmcp_backend.rs","lineNumber":543,"sourceCode":"            .map_err(|e| anyhow::anyhow!(\"rmcp call_tool '{}' failed: {}\", name, e))?;\n        Ok(convert_call_tool_result(result))\n    }\n\n    async fn list_resources(&self) -> anyhow::Result<Vec<McpResource>> {\n        let resources = self\n            .peer\n            .list_all_resources()\n            .await\n            .map_err(|e| anyhow::anyhow!(\"rmcp list_resources failed: {}\", e))?;\n        Ok(resources.into_iter().map(convert_resource).collect())\n    }\n\n    async fn read_resource(&self, uri: &str) -> anyhow::Result<ResourceContents> {\n        let result = self\n            .peer\n            .read_resource(rmcp_model::ReadResourceRequestParams::new(uri.to_string()))\n            .await\n            .map_err(|e| anyhow::anyhow!(\"rmcp read_resource '{}' failed: {}\", uri, e))?;\n        let first = result\n            .contents\n            .into_iter()\n            .next()\n            .ok_or_else(|| anyhow::anyhow!(\"rmcp read_resource '{}' returned no contents\", uri))?;\n        Ok(convert_resource_contents(first))\n    }\n\n    async fn list_prompts(&self) -> anyhow::Result<Vec<McpPrompt>> {\n        let prompts = self\n            .peer\n            .list_all_prompts()\n            .await\n            .map_err(|e| anyhow::anyhow!(\"rmcp list_prompts failed: {}\", e))?;\n        Ok(prompts.into_iter().map(convert_prompt).collect())\n    }\n\n    async fn get_prompt(","sourceCodeStart":525,"sourceCodeEnd":561,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/mcp/src/rmcp_backend.rs#L525-L561","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Re-run list_resources and confirm the URI still exists on the server before reading.","Check the inner error text: 'not found' means stale/wrong URI; 'method not found' means no resources capability.","Fix the URI to match exactly what the server registered (scheme, host, path).","Reconnect the session if the transport closed, then retry."],"exampleFix":"// before: caching URIs forever\nlet contents = backend.read_resource(&cached_uri).await?;\n// after: refresh the resource list when a read fails\nlet contents = match backend.read_resource(&cached_uri).await {\n    Ok(c) => c,\n    Err(_) => {\n        let resources = backend.list_resources().await?;\n        let fresh = resources.iter().find(|r| r.name == resource_name)\n            .ok_or_else(|| anyhow::anyhow!(\"resource {resource_name} no longer exists\"))?;\n        backend.read_resource(&fresh.uri).await?\n    }\n};","handlingStrategy":"validation","validationCode":"async fn ensure_resource_exists(backend: &dyn McpClientBackend, uri: &str) -> anyhow::Result<()> {\n    let known = backend.list_resources().await?;\n    anyhow::ensure!(known.iter().any(|r| r.uri == uri), \"resource '{uri}' not offered by server\");\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match backend.read_resource(uri).await {\n    Ok(c) => c,\n    Err(e) if e.to_string().contains(\"not found\") => {\n        eprintln!(\"resource {uri} no longer exists; refresh resource list\");\n        ResourceContents::default()\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Always obtain URIs from list_resources rather than constructing them by hand.","Refresh the resource list after server restarts; URIs are not stable across restarts.","Match the server's exact URI scheme/template when building URIs programmatically.","Handle 'not found' distinctly from transport errors — one is permanent, the other retryable."],"tags":["mcp","jsonrpc","resources","rpc","uri"],"backgroundTag":"resource-not-found","analyzedSha":"b0637c97ec34144387cbf2f74f65df6d16a6cef1","analyzedAt":"2026-09-10T00:24:58.650Z","contentChangedAt":"2026-09-10T00:24:58.650Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}