Hmbown/CodeWhale · error

tool result content

Error message

tool result content

What it means

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.

Solutions

  1. Inspect the prepared MessageRequest before the assertion (print blocks/variants) to see which variant the content landed in.
  2. Check recent changes to the adapter projection / dangling tool-call repair that could strip ToolResult blocks.
  3. Confirm the source request actually contains a ToolResult (request_with_tool_result builds one) and that model routing uses the expected adapter.
  4. Update the matcher if ToolResult was legitimately renamed/restructured in ContentBlock.

Example fix

// before
.find_map(|block| match block {
    ContentBlock::ToolResult { content, .. } => Some(content.as_str()),
    _ => None,
})
.expect("tool result content")
// after
.find_map(|block| match block {
    ContentBlock::ToolResult { content, .. } => Some(content.as_str()),
    _ => None,
})
.unwrap_or_else(|| panic!("no ToolResult block in: {messages:#?}"))
Defensive patterns

Strategy: type-guard

Validate before calling

// rust: verify a ToolResult exists before asserting its content
assert!(request.messages.iter().any(|m| m.content.iter().any(|b| matches!(b, ContentBlock::ToolResult{..}))), "input lacks ToolResult");

Type guard

fn tool_result_content(msgs: &[MessageRequest]) -> Option<&str> {
    msgs.iter().flat_map(|m| &m.content).find_map(|b| match b {
        ContentBlock::ToolResult { content, .. } => Some(content.as_str()),
        _ => None,
    })
}

Try / catch

let content = tool_result_content(&prepared.messages)
    .unwrap_or_else(|| panic!("no ToolResult block after projection: {prepared:#?}"));

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/f0925fd4e8a7c94b. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/client.rs:8395

            metadata: None,
            thinking: None,
            reasoning_effort: None,
            stream: None,
            temperature: None,
            top_p: None,
        }
    }

    fn tool_result_content(request: &MessageRequest) -> &str {
        request
            .messages
            .iter()
            .flat_map(|message| &message.content)
            .find_map(|block| match block {
                ContentBlock::ToolResult { content, .. } => Some(content.as_str()),
                _ => None,
            })
            .expect("tool result content")
    }

    #[test]
    fn model_bound_request_repairs_dangling_tool_call_before_adapter_projection() {
        let client = client_with_config_secret_sentinels();
        let mut request = request_with_tool_result("unused");
        request.messages.pop();

        let prepared = client.prepare_model_bound_request(request);

        assert!(prepared.messages.iter().any(|message| {
            message.content.iter().any(|block| {
                matches!(
                    block,
                    ContentBlock::ToolResult {
                        tool_use_id,
                        content,
                        is_error: Some(true),

View on GitHub (pinned to 73e0f67d83)