BerriAI/litellm · error · HTTPException
messages parameter is required
Error message
messages parameter is required
What it means
Thrown by the Anthropic-compatible token counting route POST /v1/messages/count_tokens when the JSON body omits the messages field or passes an empty list. The endpoint reads data.get('messages', []), so both a missing key and [] evaluate falsy and trigger the 400. It mirrors the Anthropic Messages API contract, where messages is required exactly like on /v1/messages.
Source
Thrown at litellm/proxy/anthropic_endpoints/endpoints.py:270
```
Returns: {"input_tokens": <number>}
"""
from litellm.proxy.proxy_server import token_counter as internal_token_counter
try:
request_data: Final = await _read_request_body(request=request)
data: Final[dict] = {**request_data}
# Extract required fields
model_name: Final = data.get("model")
messages: Final = data.get("messages", [])
if not model_name:
raise HTTPException(status_code=400, detail={"error": "model parameter is required"})
if not messages:
raise HTTPException(status_code=400, detail={"error": "messages parameter is required"})
# Create TokenCountRequest for the internal endpoint
from litellm.proxy._types import TokenCountRequest
token_request: Final = TokenCountRequest(
model=model_name,
messages=messages,
tools=data.get("tools"),
system=data.get("system"),
)
# Call the internal token counter function with direct request flag set to False
token_response: Final = await internal_token_counter(
request=token_request,
call_endpoint=True,
)
_token_response_dict: dict = {}
if isinstance(token_response, TokenCountResponse):View on GitHub (pinned to 77b7c6c40c)
Solutions
- Add a non-empty messages array: [{"role": "user", "content": "Hello"}] to the request body next to model
- Verify the field is named exactly 'messages' and is a list, not a string or dict
- Validate the payload with the Anthropic count_tokens schema before sending if you build requests dynamically
Example fix
// before
curl -X POST http://localhost:4000/v1/messages/count_tokens \
-d '{"model": "claude-3-5-sonnet-20241022"}'
// after
curl -X POST http://localhost:4000/v1/messages/count_tokens \
-H "Authorization: Bearer sk-..." \
-d '{"model": "claude-3-5-sonnet-20241022", "messages": [{"role": "user", "content": "Hello Claude!"}]}' Defensive patterns
Strategy: validation
Validate before calling
def valid_count_tokens_body(body: dict) -> bool:
return bool(body.get("model")) and isinstance(body.get("messages"), list) and len(body["messages"]) > 0
if not valid_count_tokens_body(payload):
raise ValueError("count_tokens requires 'model' and a non-empty 'messages' list") Type guard
def is_non_empty_message_list(messages: object) -> bool:
return isinstance(messages, list) and len(messages) > 0 and all(
isinstance(m, dict) and isinstance(m.get("role"), str) and "content" in m
for m in messages
) Try / catch
try:
resp = requests.post(f"{base}/v1/messages/count_tokens", json=payload, headers=headers)
resp.raise_for_status()
except requests.HTTPError as e:
if e.response.status_code == 400 and "messages parameter is required" in e.response.text:
raise ValueError("payload missing messages") from e
raise Prevention
- Build count_tokens payloads through one helper that always sets model and a non-empty messages list
- Assert the Anthropic payload shape in unit tests for request builders
- Remember an empty messages list [] fails the same check as a missing field
When it happens
Trigger: POST /v1/messages/count_tokens with a body like {"model": "claude-3-sonnet-20240229"} and no messages key; sending "messages": []; sending messages under a different key name (e.g. "message" or nesting it inside "params").
Common situations: Porting an Anthropic SDK count_tokens call to litellm proxy and dropping the messages field during refactor; testing the endpoint with a minimal body; sending messages as a plain string instead of a list of role/content objects.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- model parameter is required
- Invalid first message. Should always start with 'role'='user
- Either file_data or file_id must be present in the file mess
- {error_text}
- model parameter is required
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/8658ba8bf56cb3e9.
Report an issue: GitHub.