BerriAI/litellm · error · ValueError
Missing required key 'url' in image_url dict.
Error message
Missing required key 'url' in image_url dict.
What it means
An image_url content block was given as a dict, so litellm expects {'url': ..., 'detail': ...}; the 'url' key is missing, empty, or None. With nothing to fetch or size, token counting aborts before doing any math.
Source
Thrown at litellm/litellm_core_utils/token_counter.py:592
Count tokens for an image_url content block.
Args:
image_url: The image URL data - can be a string URL or dict with 'url' and 'detail'
use_default_image_token_count: Whether to use default image token counts
Returns:
int: Number of tokens for the image
Raises:
ValueError: If image_url is invalid type or detail value is invalid
"""
if isinstance(image_url, dict):
detail: Final = image_url.get("detail", "auto")
if detail not in ["low", "high", "auto"]:
raise ValueError(f"Invalid detail value: {detail}. Expected 'low', 'high', or 'auto'.")
url: Final = image_url.get("url")
if not url:
raise ValueError("Missing required key 'url' in image_url dict.")
return calculate_img_tokens(
data=url,
mode=detail,
use_default_image_token_count=use_default_image_token_count,
)
elif isinstance(image_url, str):
if not image_url.strip():
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:View on GitHub (pinned to 6c2dcb801b)
Solutions
- Ensure every image_url dict includes a non-empty 'url' (http(s) URL or base64 data URI).
- Filter out image blocks without a url before calling token_counter.
Example fix
# before
msg = {"role": "user", "content": [{"type": "image_url", "image_url": {"detail": "high"}}]}
# after
msg = {"role": "user", "content": [{"type": "image_url", "image_url": {"url": data_uri, "detail": "high"}}]} Defensive patterns
Strategy: validation
Validate before calling
content = [b for b in content
if not (isinstance(b, dict) and b.get("type") == "image_url"
and not b.get("image_url", {}).get("url"))]
n = litellm.token_counter(model=m, messages=[{"content": content}]) Type guard
def has_url(image_url: dict) -> bool:
return bool(image_url.get("url")) Prevention
- Require url at upload-assembly time; fail the request, not the count.
- Add schema validation (e.g. pydantic) for inbound multimodal messages.
When it happens
Trigger: An image_url dict with only 'detail' and no 'url' (e.g. {"type":"image_url","image_url":{"detail":"low"}}); image_url set to {}; url explicitly None from optional access on user input.
Common situations: Building multimodal messages from partial uploads where the image field was never populated; frontends sending detail-only config blocks; dict merges that drop the url key.
Related errors
- Invalid detail value: {detail}. Expected 'low', 'high', or '
- Empty image_url string is not valid.
- Invalid image_url type: {type(image_url).__name__}. Expected
- Anthropic content missing required field: 'type'
- Missing required fields in {content_type} block: {', '.join(
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/e971d8b971b2c278.
Report an issue: GitHub.