{"record":{"id":"3e852ab1fcb13cbb","repo":"BerriAI/litellm","slug":"image-response-must-be-of-type-imageresponse-got-t-3e852a","errorCode":null,"errorMessage":"image_response must be of type ImageResponse got type={type(image_response)}","messagePattern":"image_response must be of type ImageResponse got type=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/vertex_ai/image_edit/cost_calculator.py","lineNumber":29,"sourceCode":"def cost_calculator(\n    model: str,\n    image_response: Any,\n) -> float:\n    \"\"\"\n    Vertex AI image edit cost calculator.\n\n    Mirrors image generation pricing: charge per returned image based on\n    model metadata (`output_cost_per_image`).\n    \"\"\"\n    model_info: Final = litellm.get_model_info(\n        model=model,\n        custom_llm_provider=\"vertex_ai\",\n    )\n\n    output_cost_per_image: Final[float] = model_info.get(\"output_cost_per_image\") or 0.0\n\n    if not isinstance(image_response, ImageResponse):\n        raise ValueError(f\"image_response must be of type ImageResponse got type={type(image_response)}\")\n\n    num_images: Final = len(image_response.data or [])\n    return output_cost_per_image * num_images\n","sourceCodeStart":11,"sourceCodeEnd":33,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/vertex_ai/image_edit/cost_calculator.py#L11-L33","documentation":"Litellm computes Vertex AI image-edit cost as output_cost_per_image x number of returned images. Before doing that math, the cost calculator asserts the object it was handed is a litellm.types.utils.ImageResponse. If a custom cost handler, router callback, or forked internal passes anything else (dict, httpx.Response, None), this ValueError is raised. It is an internal-contract check, not an API response error.","triggerScenarios":"Calling litellm.llms.vertex_ai.image_edit.cost_calculator.cost_calculator() (or wiring it via a custom_cost_handler / cost tracking hook) with response.json() output, an OpenAI SDK object, or a hand-built dict instead of the ImageResponse instance returned by litellm.image_edit(). Unit tests that mock the response with a plain dict also hit it.","commonSituations":"Writing a custom pricing callback for vertex_ai image-edit models; upgrading litellm versions where the cost-calculation signature tightened to require ImageResponse; helper code that re-serializes responses before passing them to cost tracking.","solutions":["Pass the ImageResponse object exactly as returned by litellm.image_edit()/litellm.aimage_edit() — do not call .json() or rebuild a dict","If you construct one yourself, build litellm.types.utils.ImageResponse(data=[ImageObject(b64_json=...)]) instead of a plain dict","In custom cost handlers, mirror the default: isinstance(resp, ImageResponse) check first, then cost = price * len(resp.data or [])","If you only have raw JSON, parse it into ImageResponse before calling the calculator"],"exampleFix":"# before\ncost = cost_calculator(model, image_response=resp.json())  # dict -> raises\n\n# after\nfrom litellm.types.utils import ImageResponse\nassert isinstance(resp, ImageResponse)\ncost = cost_calculator(model, image_response=resp)","handlingStrategy":"type-guard","validationCode":"from litellm.types.utils import ImageResponse\n\nif not isinstance(image_response, ImageResponse):\n    raise TypeError(f'cost calculation requires ImageResponse, got {type(image_response)}')","typeGuard":"from litellm.types.utils import ImageResponse\n\ndef is_image_response(obj) -> bool:\n    return isinstance(obj, ImageResponse)","tryCatchPattern":"try:\n    cost = cost_calculator(model, image_response)\nexcept ValueError as e:\n    if 'must be of type ImageResponse' in str(e):\n        log.error('cost hook received %s, skipping', type(image_response))\n    else:\n        raise","preventionTips":["Always thread the original ImageResponse object through cost hooks; never re-serialize to dict","Type-annotate cost callbacks as (model: str, image_response: ImageResponse) so mypy catches misuse","In tests, construct ImageResponse fixtures instead of plain dicts"],"tags":["vertex-ai","image-edit","cost-calculation","type-check","python"],"backgroundTag":"invalid-argument-value","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}