{"record":{"id":"4048bf96d74f6822","repo":"BerriAI/litellm","slug":"invalid-detail-value-detail-expected-low-h","errorCode":null,"errorMessage":"Invalid detail value: {detail}. Expected 'low', 'high', or 'auto'.","messagePattern":"Invalid detail value: (.+?)\\. Expected 'low', 'high', or 'auto'\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/token_counter.py","lineNumber":589,"sourceCode":"    use_default_image_token_count: bool,\n) -> int:\n    \"\"\"\n    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.\")","sourceCodeStart":571,"sourceCodeEnd":607,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/litellm_core_utils/token_counter.py#L571-L607","documentation":"For image content blocks passed as dicts, the 'detail' field must be exactly 'low', 'high', or 'auto' (default 'auto'). Any other value - including casing variants like 'High' and typos like 'medium' - is rejected before token math, because image token cost depends directly on the detail level.","triggerScenarios":"An image_url dict with detail='FULL' (wrong casing), 'medium', None, or a user-supplied detail value forwarded without validation, passed to token_counter or cost calculation.","commonSituations":"Passing user-supplied request bodies straight into token counting; API gateways forwarding non-normalized detail values; copy-paste from provider docs that use different casing.","solutions":["Normalize detail to one of low/high/auto (lowercase) before counting.","Validate at your API boundary so bad values never reach litellm."],"exampleFix":"# before\nblock = {\"type\": \"image_url\", \"image_url\": {\"url\": u, \"detail\": \"High\"}}\n\n# after\ndetail = block[\"image_url\"].get(\"detail\", \"auto\").lower()\nif detail not in (\"low\", \"high\", \"auto\"):\n    detail = \"auto\"\nblock[\"image_url\"][\"detail\"] = detail","handlingStrategy":"validation","validationCode":"for block in content:\n    iu = block.get(\"image_url\") if isinstance(block, dict) else None\n    if isinstance(iu, dict):\n        d = str(iu.get(\"detail\", \"auto\")).lower()\n        iu[\"detail\"] = d if d in (\"low\", \"high\", \"auto\") else \"auto\"","typeGuard":"def has_valid_detail(image_url: dict) -> bool:\n    return image_url.get(\"detail\", \"auto\") in (\"low\", \"high\", \"auto\")","tryCatchPattern":null,"preventionTips":["Lowercase and whitelist detail at the API boundary.","Never forward unvalidated user-supplied detail values into token counting."],"tags":["token-counter","image","validation","api-misuse"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}