{"record":{"id":"e971d8b971b2c278","repo":"BerriAI/litellm","slug":"missing-required-key-url-in-image-url-dict","errorCode":null,"errorMessage":"Missing required key 'url' in image_url dict.","messagePattern":"Missing required key 'url' in image_url dict\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/token_counter.py","lineNumber":592,"sourceCode":"    Count tokens for an image_url content block.\n\n    Args:\n        image_url: The image URL data - can be a string URL or dict with 'url' and 'detail'\n        use_default_image_token_count: Whether to use default image token counts\n\n    Returns:\n        int: Number of tokens for the image\n\n    Raises:\n        ValueError: If image_url is invalid type or detail value is invalid\n    \"\"\"\n    if isinstance(image_url, dict):\n        detail: Final = image_url.get(\"detail\", \"auto\")\n        if detail not in [\"low\", \"high\", \"auto\"]:\n            raise ValueError(f\"Invalid detail value: {detail}. Expected 'low', 'high', or 'auto'.\")\n        url: Final = image_url.get(\"url\")\n        if not url:\n            raise ValueError(\"Missing required key 'url' in image_url dict.\")\n        return calculate_img_tokens(\n            data=url,\n            mode=detail,\n            use_default_image_token_count=use_default_image_token_count,\n        )\n    elif isinstance(image_url, str):\n        if not image_url.strip():\n            raise ValueError(\"Empty image_url string is not valid.\")\n        return calculate_img_tokens(\n            data=image_url,\n            mode=\"auto\",\n            use_default_image_token_count=use_default_image_token_count,\n        )\n    else:\n        raise ValueError(f\"Invalid image_url type: {type(image_url).__name__}. Expected str or dict with 'url' field.\")\n\n\ndef _validate_anthropic_content(content: Mapping[str, Any]) -> type:","sourceCodeStart":574,"sourceCodeEnd":610,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/litellm_core_utils/token_counter.py#L574-L610","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nmsg = {\"role\": \"user\", \"content\": [{\"type\": \"image_url\", \"image_url\": {\"detail\": \"high\"}}]}\n\n# after\nmsg = {\"role\": \"user\", \"content\": [{\"type\": \"image_url\", \"image_url\": {\"url\": data_uri, \"detail\": \"high\"}}]}","handlingStrategy":"validation","validationCode":"content = [b for b in content\n           if not (isinstance(b, dict) and b.get(\"type\") == \"image_url\"\n                   and not b.get(\"image_url\", {}).get(\"url\"))]\nn = litellm.token_counter(model=m, messages=[{\"content\": content}])","typeGuard":"def has_url(image_url: dict) -> bool:\n    return bool(image_url.get(\"url\"))","tryCatchPattern":null,"preventionTips":["Require url at upload-assembly time; fail the request, not the count.","Add schema validation (e.g. pydantic) for inbound multimodal messages."],"tags":["token-counter","image","validation","missing-field"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}