This commit is contained in:
Techboy bebop 2026-10-02 23:52:10 -04:00 • committed by GitHub
commit 4b402a0eec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 122 additions and 4 deletions

View file

@ -962,9 +962,9 @@ def image_edit(
@client
async def aimage_edit(
image: FileTypes | list[FileTypes],
model: str,
prompt: str,
image: FileTypes | list[FileTypes] | None = None,
model: str | None = None,
prompt: str | None = None,
mask: str | None = None,
n: int | None = None,
quality: str | ImageGenerationRequestQuality | None = None,
@ -996,10 +996,24 @@ async def aimage_edit(
loop: Final = asyncio.get_event_loop()
kwargs["async_call"] = True
if image is None or (isinstance(image, list) and len(image) == 0):
message = "Missing required parameter: 'image'."
raise litellm.BadRequestError(
message=message,
model=model or "unknown",
llm_provider=custom_llm_provider or "openai",
body={ # mutable-ok: BadRequestError requires an OpenAI-shaped error body dict
"message": message,
"type": "invalid_request_error",
"param": "image",
"code": "missing_required_parameter",
},
)
# get custom llm provider so we can use this for mapping exceptions
if custom_llm_provider is None:
_, custom_llm_provider, _, _ = litellm.get_llm_provider(
model=model, api_base=local_vars.get("base_url", None)
model=model or DEFAULT_IMAGE_ENDPOINT_MODEL, api_base=local_vars.get("base_url", None)
)
images: Final = image if isinstance(image, list) else [image]

View file

@ -0,0 +1,104 @@
"""Regression tests for https://github.com/BerriAI/litellm/issues/42185
Lives under litellm_core_utils so the core-utils CI shard collects it (misc currently lists missing paths and collects zero tests).
POST /v1/images/edits without a multipart `image` used to TypeError inside
aimage_edit (required positional arg) and surface as HTTP 500. A missing client
field must be BadRequestError 400.
"""
from collections.abc import Mapping
import pytest
import litellm
from litellm.images.main import aimage_edit
_MISSING_IMAGE_MESSAGE = "Missing required parameter: 'image'."
_MISSING_IMAGE_BODY = {
"message": _MISSING_IMAGE_MESSAGE,
"type": "invalid_request_error",
"param": "image",
"code": "missing_required_parameter",
}
def _assert_missing_image_400(
err: litellm.BadRequestError,
*,
model: str,
llm_provider: str,
) -> None:
message = str(err)
assert err.status_code == 400
assert _MISSING_IMAGE_MESSAGE in message
assert "positional argument" not in message
assert "TypeError" not in message
assert err.model == model
assert err.llm_provider == llm_provider
assert err.param == "image"
body = err.body
assert isinstance(body, Mapping)
for key, value in _MISSING_IMAGE_BODY.items():
assert body[key] == value
@pytest.mark.asyncio
@pytest.mark.parametrize(
"kwargs",
[
{"model": "openai/gpt-image-1", "prompt": "add a hat"},
{"model": "openai/gpt-image-1", "prompt": "add a hat", "image": None},
{"model": "openai/gpt-image-1", "prompt": "add a hat", "image": []},
],
ids=["omitted", "none", "empty_list"],
)
async def test_aimage_edit_missing_image_raises_bad_request(kwargs: Mapping[str, object]) -> None:
with pytest.raises(litellm.BadRequestError) as exc_info:
await litellm.aimage_edit(**kwargs)
_assert_missing_image_400(
exc_info.value,
model="openai/gpt-image-1",
llm_provider="openai",
)
@pytest.mark.asyncio
async def test_aimage_edit_direct_import_missing_image_raises_bad_request() -> None:
with pytest.raises(litellm.BadRequestError) as exc_info:
await aimage_edit(model="gpt-image-1", prompt="add a hat")
_assert_missing_image_400(
exc_info.value,
model="gpt-image-1",
llm_provider="openai",
)
@pytest.mark.asyncio
async def test_aimage_edit_missing_image_keeps_custom_llm_provider() -> None:
with pytest.raises(litellm.BadRequestError) as exc_info:
await litellm.aimage_edit(
model="gpt-image-1",
prompt="add a hat",
custom_llm_provider="azure",
)
_assert_missing_image_400(
exc_info.value,
model="gpt-image-1",
llm_provider="azure",
)
@pytest.mark.asyncio
async def test_aimage_edit_missing_image_defaults_model_to_unknown() -> None:
with pytest.raises(litellm.BadRequestError) as exc_info:
await aimage_edit(prompt="add a hat")
_assert_missing_image_400(
exc_info.value,
model="unknown",
llm_provider="openai",
)