aaif-goose/goose · error

Missing thinking content

Error message

Missing thinking content

What it means

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.

Source

Thrown at crates/goose-provider-types/src/formats/snowflake.rs:268

                let name = content
                    .get("name")
                    .and_then(|n| n.as_str())
                    .ok_or_else(|| anyhow!("Missing tool_use name"))?
                    .to_string();

                let input = content
                    .get("input")
                    .ok_or_else(|| anyhow!("Missing tool input"))?
                    .clone();

                let tool_call = CallToolRequestParams::new(name).with_arguments(object(input));
                message = message.with_tool_request(id, Ok(tool_call));
            }
            Some("thinking") => {
                let thinking = content
                    .get("thinking")
                    .and_then(|t| t.as_str())
                    .ok_or_else(|| anyhow!("Missing thinking content"))?;
                let signature = content
                    .get("signature")
                    .and_then(|s| s.as_str())
                    .ok_or_else(|| anyhow!("Missing thinking signature"))?;
                message = message.with_thinking(thinking, signature);
            }
            Some("redacted_thinking") => {
                let data = content
                    .get("data")
                    .and_then(|d| d.as_str())
                    .ok_or_else(|| anyhow!("Missing redacted_thinking data"))?;
                message = message.with_redacted_thinking(data);
            }
            _ => {
                // Ignore unrecognized content types
            }
        }
    }

View on GitHub (pinned to 3810898a74)

Solutions

  1. Log the raw thinking block and confirm the "thinking" key exists and holds a string
  2. Verify the model/endpoint actually produces Snowflake Cortex-format thinking blocks (thinking + signature at the block level)
  3. Update fixtures to include both "thinking" and "signature"
  4. If partial thinking blocks are expected from your endpoint, skip blocks missing the text instead of failing the message

Example fix

// before
let thinking = content
    .get("thinking")
    .and_then(|t| t.as_str())
    .ok_or_else(|| anyhow!("Missing thinking content"))?;

// after - skip incomplete thinking blocks
let thinking = match content.get("thinking").and_then(|t| t.as_str()) {
    Some(t) => t,
    None => {
        tracing::warn!("skipping thinking block without content");
        continue;
    }
};
Defensive patterns

Strategy: validation

Validate before calling

for block in content_list {
    if block.get("type").and_then(|t| t.as_str()) == Some("thinking")
        && block.get("thinking").and_then(|t| t.as_str()).is_none()
    {
        anyhow::bail!("thinking block without string thinking field: {block}");
    }
}

Type guard

fn thinking_block_has_text(block: &serde_json::Value) -> bool {
    if block.get("type").and_then(|t| t.as_str()) != Some("thinking") {
        return true;
    }
    block.get("thinking").and_then(|v| v.as_str()).is_some()
}

Try / catch

match response_to_message(&response) {
    Ok(msg) => msg,
    Err(err) if err.to_string().contains("Missing thinking content") => {
        tracing::warn!("response with unusable thinking block: {err}");
        Message::assistant()
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

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

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

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/4743730fe5b34b00. Report an issue: GitHub.