{"record":{"id":"f0925fd4e8a7c94b","repo":"Hmbown/CodeWhale","slug":"tool-result-content","errorCode":null,"errorMessage":"tool result content","messagePattern":"tool result content","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/client.rs","lineNumber":8395,"sourceCode":"            metadata: None,\n            thinking: None,\n            reasoning_effort: None,\n            stream: None,\n            temperature: None,\n            top_p: None,\n        }\n    }\n\n    fn tool_result_content(request: &MessageRequest) -> &str {\n        request\n            .messages\n            .iter()\n            .flat_map(|message| &message.content)\n            .find_map(|block| match block {\n                ContentBlock::ToolResult { content, .. } => Some(content.as_str()),\n                _ => None,\n            })\n            .expect(\"tool result content\")\n    }\n\n    #[test]\n    fn model_bound_request_repairs_dangling_tool_call_before_adapter_projection() {\n        let client = client_with_config_secret_sentinels();\n        let mut request = request_with_tool_result(\"unused\");\n        request.messages.pop();\n\n        let prepared = client.prepare_model_bound_request(request);\n\n        assert!(prepared.messages.iter().any(|message| {\n            message.content.iter().any(|block| {\n                matches!(\n                    block,\n                    ContentBlock::ToolResult {\n                        tool_use_id,\n                        content,\n                        is_error: Some(true),","sourceCodeStart":8377,"sourceCodeEnd":8413,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/client.rs#L8377-L8413","documentation":"A panic from `.expect(\"tool result content\")` on a find_map over prepared messages in crates/tui/src/client.rs. The helper asserts that the projected request contains at least one ContentBlock::ToolResult and returns its content string; if no ToolResult block exists in any message, the Option is None and the test panics — meaning the adapter dropped, transformed, or mis-projected the tool result.","triggerScenarios":"Tests call request_with_tool_result/this helper and the adapter projection (e.g. dangling tool-call repair or adapter projection changes) removes or rewrites the ToolResult block so `messages.iter().flat_map(content).find_map(ToolResult)` finds nothing.","commonSituations":"Refactors of the adapter projection or tool-call repair logic that convert/strip ToolResult blocks; request construction that puts content in a different block variant; model-name changes routing to a different adapter.","solutions":["Inspect the prepared MessageRequest before the assertion (print blocks/variants) to see which variant the content landed in.","Check recent changes to the adapter projection / dangling tool-call repair that could strip ToolResult blocks.","Confirm the source request actually contains a ToolResult (request_with_tool_result builds one) and that model routing uses the expected adapter.","Update the matcher if ToolResult was legitimately renamed/restructured in ContentBlock."],"exampleFix":"// before\n.find_map(|block| match block {\n    ContentBlock::ToolResult { content, .. } => Some(content.as_str()),\n    _ => None,\n})\n.expect(\"tool result content\")\n// after\n.find_map(|block| match block {\n    ContentBlock::ToolResult { content, .. } => Some(content.as_str()),\n    _ => None,\n})\n.unwrap_or_else(|| panic!(\"no ToolResult block in: {messages:#?}\"))","handlingStrategy":"type-guard","validationCode":"// rust: verify a ToolResult exists before asserting its content\nassert!(request.messages.iter().any(|m| m.content.iter().any(|b| matches!(b, ContentBlock::ToolResult{..}))), \"input lacks ToolResult\");","typeGuard":"fn tool_result_content(msgs: &[MessageRequest]) -> Option<&str> {\n    msgs.iter().flat_map(|m| &m.content).find_map(|b| match b {\n        ContentBlock::ToolResult { content, .. } => Some(content.as_str()),\n        _ => None,\n    })\n}","tryCatchPattern":"let content = tool_result_content(&prepared.messages)\n    .unwrap_or_else(|| panic!(\"no ToolResult block after projection: {prepared:#?}\"));","preventionTips":["After adapter/projection refactors, dump the prepared request before assertions.","Keep ContentBlock matchers in sync with enum changes via exhaustive matches.","Pin tests to behavior (repaired content present) rather than internal projection order."],"tags":["rust","test-assertion","adapter-projection","tool-result"],"backgroundTag":"unexpected-response-shape","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}