BerriAI/litellm · error · ValueError

Anthropic content missing required field: 'type'

Error message

Anthropic content missing required field: 'type'

What it means

While counting Anthropic-format messages, a content block dict lacks the required 'type' key. Anthropic content blocks are discriminated solely by 'type' (tool_use, tool_result, text, ...); without it litellm cannot select a TypedDict to validate against, so it fails fast.

Source

Thrown at litellm/litellm_core_utils/token_counter.py:618

            raise ValueError("Empty image_url string is not valid.")
        return calculate_img_tokens(
            data=image_url,
            mode="auto",
            use_default_image_token_count=use_default_image_token_count,
        )
    else:
        raise ValueError(f"Invalid image_url type: {type(image_url).__name__}. Expected str or dict with 'url' field.")


def _validate_anthropic_content(content: Mapping[str, Any]) -> type:
    """
    Validate and determine which Anthropic TypedDict applies.

    Returns the corresponding TypedDict class if recognized, otherwise raises.
    """
    content_type: Final = content.get("type")
    if not content_type:
        raise ValueError("Anthropic content missing required field: 'type'")

    mapping: Final = {
        "tool_use": AnthropicMessagesToolUseParam,
        "tool_result": AnthropicMessagesToolResultParam,
    }

    expected_cls: Final = mapping.get(content_type)
    if expected_cls is None:
        raise ValueError(f"Unknown Anthropic content type: '{content_type}'")

    missing: Final = [k for k in getattr(expected_cls, "__required_keys__", set()) if k not in content]
    if missing:
        raise ValueError(f"Missing required fields in {content_type} block: {', '.join(missing)}")

    return expected_cls


def _count_anthropic_content(

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Ensure every content block dict has an explicit 'type' ("text", "image", "tool_use", "tool_result", "thinking").
  2. For plain text prefer a plain string instead of a dict block.

Example fix

# before
content = [{"text": "What's the weather?"}]

# after
content = [{"type": "text", "text": "What's the weather?"}]
Defensive patterns

Strategy: validation

Validate before calling

for block in content:
    if isinstance(block, dict) and not block.get("type"):
        block["type"] = "text"  # or raise, depending on your policy

Type guard

def has_type_key(block: dict) -> bool:
    return bool(block.get("type"))

Prevention

When it happens

Trigger: Content blocks like {"text": "hi"} (type omitted), a block with type=None, or blocks assembled from dict merges that dropped the key, passed to token_counter on the Anthropic path.

Common situations: Hand-converting OpenAI-style content to Anthropic format; storing blocks without the discriminator; None 'type' from optional-access patterns.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/8f3577659803b9bf. Report an issue: GitHub.