BerriAI/litellm · error · ValueError

Message must have a 'content' field

Error message

Message {i} must have a 'content' field

What it means

Raised when message i in a Converse-format count-tokens request is a dict with a 'role' but no 'content' key. Content is what actually gets tokenized, so a message without it cannot contribute to a count; the error names the index of the offending message.

Solutions

  1. Add content to message i, even if empty: {'role': 'user', 'content': ''} (empty content passes this validator)
  2. Rename alternate keys to 'content' when porting from other formats
  3. When deleting content for redaction, keep the key with an empty value rather than removing it

Example fix

# before
messages = [{'role': 'user'}]

# after
messages = [{'role': 'user', 'content': 'Hello, world'}]
Defensive patterns

Strategy: type-guard

Validate before calling

def assert_content_present(messages: list[dict]) -> None:
    for i, m in enumerate(messages):
        if 'content' not in m:
            raise ValueError(f'message {i} missing content (use "" if empty by design)')

Type guard

def messages_have_content(messages: list) -> bool:
    return all(isinstance(m, dict) and 'content' in m for m in messages)

Try / catch

try:
    handler.count_tokens(body)
except ValueError as e:
    m = re.search(r"Message (\d+) must have a 'content' field", str(e))
    if m:
        i = int(m.group(1))
        body['messages'][i].setdefault('content', '')
        handler.count_tokens(body)
    else:
        raise

Prevention

When it happens

Trigger: messages=[{'role': 'user'}] (role-only); content stored under different keys ('text', 'parts', 'blocks'); messages constructed from templates where the content placeholder was never filled and the key was omitted entirely.

Common situations: Migrating from APIs whose content field is named 'text'; emptying a message for moderation/redaction and deleting the key instead of setting it to '' or []; optional-content code paths that use dict.pop('content').

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/cc379b011ade9351. Report an issue: GitHub.

Appendix: source

Thrown at litellm/llms/bedrock/count_tokens/transformation.py:277

        if input_type == "converse":
            # Validate Converse format (messages-based)
            messages: Final = request_data.get("messages", [])
            if not messages:
                raise ValueError("messages parameter is required for Converse input")

            if not isinstance(messages, list):
                raise ValueError("messages must be a list")

            for i, message in enumerate(messages):
                if not isinstance(message, dict):
                    raise ValueError(f"Message {i} must be a dictionary")

                if "role" not in message:
                    raise ValueError(f"Message {i} must have a 'role' field")

                if "content" not in message:
                    raise ValueError(f"Message {i} must have a 'content' field")
        else:
            # For InvokeModel format, we need at least some content to count tokens
            # The content structure varies by model, so we do minimal validation
            if len(request_data) <= 1:  # Only has 'model' field
                raise ValueError("Request must contain content to count tokens")

View on GitHub (pinned to 77b7c6c40c)