Summary
LiteLLM's ImageURLListItem TypedDict defines index as a required field, but some providers (e.g. OpenRouter) no longer include it in image responses. This causes a Pydantic validation error when LiteLLM constructs its Message object:
pydantic_core._pydantic_core.ValidationError: 1 validation error for Message
images.0.index
Field required [type=missing, input_value={'type': 'image_url', 'im...}, input_type=dict]
Root cause
litellm/types/llms/openai.py — ImageURLListItem is a TypedDict with index: int as a required field (not total=False, no NotRequired)
litellm/types/utils.py — Message.images is typed as Optional[List[ImageURLListItem]]
litellm/litellm_core_utils/llm_response_utils/convert_dict_to_response.py — When constructing the Message, images from the provider response are passed through, but OpenRouter returns images like {"type": "image_url", "image_url": {"url": "data:image/png;base64,..."}} without an index field
- Pydantic validates the
ImageURLListItem TypedDict and fails because index is required but missing
Fix
Added patch_image_url_list_item() to litellm_overrides.py which monkey-patches index to NotRequired[int]. This is called during apply_litellm_patches().
Test plan
Summary
LiteLLM's
ImageURLListItemTypedDict definesindexas a required field, but some providers (e.g. OpenRouter) no longer include it in image responses. This causes a Pydantic validation error when LiteLLM constructs itsMessageobject:Root cause
litellm/types/llms/openai.py—ImageURLListItemis aTypedDictwithindex: intas a required field (nottotal=False, noNotRequired)litellm/types/utils.py—Message.imagesis typed asOptional[List[ImageURLListItem]]litellm/litellm_core_utils/llm_response_utils/convert_dict_to_response.py— When constructing theMessage, images from the provider response are passed through, but OpenRouter returns images like{"type": "image_url", "image_url": {"url": "data:image/png;base64,..."}}without anindexfieldImageURLListItemTypedDict and fails becauseindexis required but missingFix
Added
patch_image_url_list_item()tolitellm_overrides.pywhich monkey-patchesindextoNotRequired[int]. This is called duringapply_litellm_patches().Test plan
test_patch_image_url_list_item_makes_index_optionalverifiesMessagecan be constructed withoutindex