{"record":{"id":"4743730fe5b34b00","repo":"aaif-goose/goose","slug":"missing-thinking-content-474373","errorCode":null,"errorMessage":"Missing thinking content","messagePattern":"Missing thinking content","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-provider-types/src/formats/snowflake.rs","lineNumber":268,"sourceCode":"                let name = content\n                    .get(\"name\")\n                    .and_then(|n| n.as_str())\n                    .ok_or_else(|| anyhow!(\"Missing tool_use name\"))?\n                    .to_string();\n\n                let input = content\n                    .get(\"input\")\n                    .ok_or_else(|| anyhow!(\"Missing tool input\"))?\n                    .clone();\n\n                let tool_call = CallToolRequestParams::new(name).with_arguments(object(input));\n                message = message.with_tool_request(id, Ok(tool_call));\n            }\n            Some(\"thinking\") => {\n                let thinking = content\n                    .get(\"thinking\")\n                    .and_then(|t| t.as_str())\n                    .ok_or_else(|| anyhow!(\"Missing thinking content\"))?;\n                let signature = content\n                    .get(\"signature\")\n                    .and_then(|s| s.as_str())\n                    .ok_or_else(|| anyhow!(\"Missing thinking signature\"))?;\n                message = message.with_thinking(thinking, signature);\n            }\n            Some(\"redacted_thinking\") => {\n                let data = content\n                    .get(\"data\")\n                    .and_then(|d| d.as_str())\n                    .ok_or_else(|| anyhow!(\"Missing redacted_thinking data\"))?;\n                message = message.with_redacted_thinking(data);\n            }\n            _ => {\n                // Ignore unrecognized content types\n            }\n        }\n    }","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-provider-types/src/formats/snowflake.rs#L250-L286","documentation":"response_to_message handles Snowflake Cortex thinking blocks (extended reasoning). A content_list entry of type \"thinking\" must carry a string field thinking (the reasoning text). If the key is missing or not a string, conversion fails with 'Missing thinking content'. The signature is required next, so reaching that error means this field was fine.","triggerScenarios":"A {\"type\":\"thinking\",...} block without a string \"thinking\" member — e.g. a signature-only block, a renamed field (Anthropic native uses \"thinking\" inside a different envelope), or redacted/placeholder thinking emitted without text.","commonSituations":"Switching a Cortex model to a reasoning variant whose response schema differs from expectations; proxies forwarding Anthropic-native thinking blocks into content_list without adaptation; fixtures with signature but no thinking text.","solutions":["Log the raw thinking block and confirm the \"thinking\" key exists and holds a string","Verify the model/endpoint actually produces Snowflake Cortex-format thinking blocks (thinking + signature at the block level)","Update fixtures to include both \"thinking\" and \"signature\"","If partial thinking blocks are expected from your endpoint, skip blocks missing the text instead of failing the message"],"exampleFix":"// before\nlet thinking = content\n    .get(\"thinking\")\n    .and_then(|t| t.as_str())\n    .ok_or_else(|| anyhow!(\"Missing thinking content\"))?;\n\n// after - skip incomplete thinking blocks\nlet thinking = match content.get(\"thinking\").and_then(|t| t.as_str()) {\n    Some(t) => t,\n    None => {\n        tracing::warn!(\"skipping thinking block without content\");\n        continue;\n    }\n};","handlingStrategy":"validation","validationCode":"for block in content_list {\n    if block.get(\"type\").and_then(|t| t.as_str()) == Some(\"thinking\")\n        && block.get(\"thinking\").and_then(|t| t.as_str()).is_none()\n    {\n        anyhow::bail!(\"thinking block without string thinking field: {block}\");\n    }\n}","typeGuard":"fn thinking_block_has_text(block: &serde_json::Value) -> bool {\n    if block.get(\"type\").and_then(|t| t.as_str()) != Some(\"thinking\") {\n        return true;\n    }\n    block.get(\"thinking\").and_then(|v| v.as_str()).is_some()\n}","tryCatchPattern":"match response_to_message(&response) {\n    Ok(msg) => msg,\n    Err(err) if err.to_string().contains(\"Missing thinking content\") => {\n        tracing::warn!(\"response with unusable thinking block: {err}\");\n        Message::assistant()\n    }\n    Err(err) => return Err(err),\n}","preventionTips":["Confirm the model variant actually emits Cortex-format thinking blocks before enabling extended reasoning","Map Anthropic-native thinking blocks explicitly when bridging formats","Include thinking text (and signature) in every reasoning fixture"],"tags":["rust","snowflake","cortex","reasoning","parsing"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}