microsoft/semantic-kernel · error · ServiceInvalidRequestError

Provide either 'image_paths' or 'image_files', and only one.

Error message

Provide either 'image_paths' or 'image_files', and only one.

What it means

Raised by edit_image when the image source arguments are inconsistent. It requires exactly one of image_paths or image_files: if both are None (no input images) or both are not None (ambiguous), it throws ServiceInvalidRequestError (subclass of ServiceResponseException).

Source

Thrown at python/semantic_kernel/connectors/ai/open_ai/services/open_ai_text_to_image_base.py:212

            ```python
            with open("./new_images/img_1.png", "rb") as f:
                results = await service.edit_image(
                    prompt="Make the cat wear a wizard hat",
                    image_files=[f],
                )
            ```
        """
        if not settings:
            settings = OpenAITextToImageExecutionSettings(**kwargs)
        if not isinstance(settings, OpenAITextToImageExecutionSettings):
            settings = OpenAITextToImageExecutionSettings.from_prompt_execution_settings(settings)
        settings.prompt = prompt

        if not settings.prompt:
            raise ServiceInvalidRequestError("Prompt is required.")
        if (image_paths is None and image_files is None) or (image_paths is not None and image_files is not None):
            raise ServiceInvalidRequestError("Provide either 'image_paths' or 'image_files', and only one.")

        images: list[FileTypes] = []
        if image_paths is not None:
            images = [Path(p) for p in image_paths]
        elif image_files is not None:
            images = list(image_files)

        mask: FileTypes | Omit = omit
        if mask_path is not None:
            mask = Path(mask_path)
        elif mask_file is not None:
            mask = mask_file

        response: ImagesResponse = await self._send_image_edit_request(
            image=images,
            mask=mask,
            settings=settings,
        )

View on GitHub (pinned to c028a0c7dc)

Solutions

  1. Provide exactly one source: await service.edit_image(prompt='...', image_paths=['./a.png'])
  2. Or use file objects only: await service.edit_image(prompt='...', image_files=[f])
  3. Add a precondition in your wrapper that asserts exactly one of the two is provided

Example fix

# before (both provided)
await service.edit_image(prompt="...", image_paths=["./a.png"], image_files=[f])

# after (exactly one)
await service.edit_image(prompt="...", image_paths=["./a.png"])
Defensive patterns

Strategy: validation

Validate before calling

if (image_paths is None) == (image_files is None):
    raise ValueError("Provide exactly one of image_paths or image_files")
await service.edit_image(prompt=prompt, image_paths=image_paths, image_files=image_files)

Type guard

def exactly_one_image_source(
    image_paths: list[str] | None, image_files: list | None
) -> bool:
    return (image_paths is None) ^ (image_files is None)

Try / catch

from semantic_kernel.exceptions.service_exceptions import ServiceInvalidRequestError

try:
    res = await service.edit_image(prompt=p, image_paths=paths, image_files=files)
except ServiceInvalidRequestError as e:
    if "image_paths" in str(e):
        # fix the call to pass exactly one source
        ...
    raise

Prevention

When it happens

Trigger: Calling edit_image with neither image_paths nor image_files, OR passing both at once. The guard is (both None) OR (both not None).

Common situations: Caller defaulted both parameters to None and forgot to populate one; a generic wrapper passes both a path list and a file list; refactor left both arguments set.

Related errors


AI-assisted analysis of microsoft/semantic-kernel@c028a0c7dc (2026-08-13). Data as JSON: /api/errors/dcad73b92f37bf05. Report an issue: GitHub.