{"record":{"id":"f85cb09318df7a72","repo":"aaif-goose/goose","slug":"no-agent-visible-tool-pair-found-for-tool-id","errorCode":null,"errorMessage":"No agent-visible tool pair found for tool id: {}","messagePattern":"No agent-visible tool pair found for tool id: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose/src/context_mgmt/mod.rs","lineNumber":439,"sourceCode":"            })\n        })\n        .cloned()\n        .collect::<Vec<_>>();\n    let matching_messages =\n        Conversation::new_unvalidated(matching_messages).agent_visible_messages();\n\n    let has_request = matching_messages.iter().any(|message| {\n        message.content.iter().any(\n            |content| matches!(content, MessageContent::ToolRequest(request) if request.id == tool_id),\n        )\n    });\n    let has_response = matching_messages.iter().any(|message| {\n        message.content.iter().any(\n            |content| matches!(content, MessageContent::ToolResponse(response) if response.id == tool_id),\n        )\n    });\n    if !has_request || !has_response {\n        return Err(anyhow::anyhow!(\n            \"No agent-visible tool pair found for tool id: {}\",\n            tool_id\n        ));\n    }\n    Ok(matching_messages)\n}\n\npub async fn summarize_tool_call(\n    provider: &dyn Provider,\n    model_config: &ModelConfig,\n    session_id: &str,\n    conversation: &Conversation,\n    tool_id: &str,\n) -> Result<Message> {\n    let matching_messages = agent_visible_tool_pair(conversation, tool_id)?;\n\n    let formatted = matching_messages\n        .iter()","sourceCodeStart":421,"sourceCodeEnd":457,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose/src/context_mgmt/mod.rs#L421-L457","documentation":"Before summarizing a tool call, goose gathers the agent-visible messages for the session and requires BOTH a MessageContent::ToolRequest and a MessageContent::ToolResponse whose id equals the requested tool id. This error means one half of the pair is missing (or the id matches nothing), so the call cannot be summarized.","triggerScenarios":"Calling summarize_tool_call with a tool id that is stale (from before a compaction/truncation that dropped one half), a request whose response has not arrived yet (tool still running), or an id typo. Messages hidden from the agent also never match.","commonSituations":"Summarizing old tool calls after context truncation removed the request or response; summarizing while the tool is still executing; replaying a logged tool id against a different conversation.","solutions":["Verify the tool id refers to a completed call in the CURRENT conversation — both a ToolRequest and a ToolResponse with that exact id must be present in agent-visible messages","If the tool is still running, wait for its response before summarizing","Re-discover valid ids by scanning the live conversation instead of using logged/historical ids"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"use goose::messages::{MessageContent, Conversation};\n\nfn has_agent_visible_tool_pair(conversation: &Conversation, tool_id: &str) -> bool {\n    let mut has_request = false;\n    let mut has_response = false;\n    for m in conversation.messages().iter().filter(|m| m.is_agent_visible()) {\n        for c in &m.content {\n            match c {\n                MessageContent::ToolRequest(r) if r.id == tool_id => has_request = true,\n                MessageContent::ToolResponse(r) if r.id == tool_id => has_response = true,\n                _ => {}\n            }\n        }\n    }\n    has_request && has_response\n}\n\n// before summarize_tool_call:\nif !has_agent_visible_tool_pair(&conversation, tool_id) { /* skip or re-fetch the id */ }","typeGuard":null,"tryCatchPattern":"match summarize_tool_call(provider, &model_config, session_id, &conversation, tool_id).await {\n    Err(e) if e.to_string().starts_with(\"No agent-visible tool pair found\") => {\n        // the id is stale or the call is incomplete: re-scan the live conversation for valid ids\n    }\n    other => other?,\n}","preventionTips":["Take tool ids from the current in-memory conversation, never from logs or earlier sessions","Only summarize completed calls (response received)","Re-validate ids after any compaction or truncation step"],"tags":["context-management","tool-calls","summarization"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}