{"record":{"id":"dbc2e26bd73a1ae2","repo":"Kuberwastaken/claurst","slug":"rmcp-read-resource-returned-no-contents","errorCode":null,"errorMessage":"rmcp read_resource '{}' returned no contents","messagePattern":"rmcp read_resource '(.+?)' returned no contents","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src-rust/crates/mcp/src/rmcp_backend.rs","lineNumber":548,"sourceCode":"        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(\n        &self,\n        name: &str,\n        arguments: Option<HashMap<String, String>>,\n    ) -> anyhow::Result<GetPromptResult> {\n        let mut params = rmcp_model::GetPromptRequestParams::new(name.to_string());","sourceCodeStart":530,"sourceCodeEnd":566,"githubUrl":"https://github.com/Kuberwastaken/claurst/blob/b0637c97ec34144387cbf2f74f65df6d16a6cef1/src-rust/crates/mcp/src/rmcp_backend.rs#L530-L566","documentation":"Raised in `RmcpClientBackend::read_resource` after a SUCCESSFUL `resources/read` round-trip: the server returned a result whose `contents` array is empty, and since this backend returns a single `ResourceContents`, `.into_iter().next()` finds nothing and this explicit error is thrown. Unlike error 196 this is not a transport/protocol failure — the server answered, but had no content for the URI. The URI is embedded in the message.","triggerScenarios":"Calling `read_resource(uri)` for a resource the server knows about but that currently has no content: an empty file backing the resource, a resource whose generation failed server-side, a legitimately empty resource (empty log, empty query result), or a server bug returning `contents: []` instead of an error.","commonSituations":"Reading an empty text file exposed as an MCP resource; reading a resource computed on demand where the underlying source returned nothing; MCP servers that model 'not found yet' as an empty contents list rather than a JSON-RPC error; pipelines that assume every listed resource has at least one content part.","solutions":["Treat empty-contents as a legitimate outcome: match on this error and return an empty/default value instead of failing.","Verify on the server side whether the resource backing data is empty or generation failed.","If the resource should have content, check the server logs for errors in its resource provider.","Prefer checking the resource's metadata (size/mime) from list_resources before reading."],"exampleFix":"// before: any read failure aborts the pipeline\nlet contents = backend.read_resource(uri).await?;\n// after: accept empty resources as empty content\nlet contents = match backend.read_resource(uri).await {\n    Ok(c) => c,\n    Err(e) if e.to_string().ends_with(\"returned no contents\") => ResourceContents::empty(),\n    Err(e) => return Err(e),\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match backend.read_resource(uri).await {\n    Ok(contents) => contents,\n    Err(e) if e.to_string().ends_with(\"returned no contents\") => {\n        tracing::info!(uri, \"resource has no content; using empty default\");\n        ResourceContents::default()\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Treat empty contents as a valid outcome for resources backed by empty or on-demand data.","Check resource metadata (size, mime) from list_resources before reading where available.","Never assume a listed resource always yields at least one content part.","If a resource should have content, investigate the server-side provider rather than retrying the read."],"tags":["mcp","resources","empty-result","rpc","content"],"backgroundTag":"empty-result-set","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"}