agentscope-ai/agentscope · error · ValueError

Unsupported image source type: {type(source)}

Error message

Unsupported image source type: {type(source)}

What it means

The OpenAI formatter's _format_image_source handles URLSource and Base64Source only (base64 becomes a data: URL, remote URLs pass through as-is); any other source type raises this ValueError.

Source

Thrown at src/agentscope/formatter/_openai_formatter.py:115

                A dictionary with ``"type": "image_url"`` in OpenAI format.
        """
        if isinstance(source, Base64Source):
            url = f"data:{source.media_type};base64,{source.data}"

        elif isinstance(source, URLSource):
            url_str = str(source.url)
            if url_str.startswith("file://"):
                # Local file — read and encode as base64 data URI
                local_path = url_str.removeprefix("file://")
                with open(local_path, "rb") as f:
                    encoded = base64.b64encode(f.read()).decode("utf-8")
                url = f"data:{source.media_type};base64,{encoded}"
            else:
                # Remote URL — pass through as-is
                url = url_str

        else:
            raise ValueError(f"Unsupported image source type: {type(source)}")

        return {
            "type": "image_url",
            "image_url": {"url": url},
        }

    @staticmethod
    def _format_audio_source(
        source: URLSource | Base64Source,
    ) -> dict[str, Any]:
        """Convert an audio source to OpenAI input_audio format.

        Local ``file://`` URLs are read from disk. Remote URLs are downloaded.
        Only ``wav`` and ``mp3`` formats are supported by the OpenAI API.

        Args:
            source (`URLSource | Base64Source`):
                The audio source to convert.

View on GitHub (pinned to e90f1c7592)

Solutions

  1. Convert the local image to Base64Source and let the formatter emit a data: URL
  2. Or upload/host the image and use URLSource (OpenAI fetches remote URLs)
  3. Validate sources before formatting and downgrade unsupported image blocks to text

Example fix

# before
ImageBlock(source=LocalFileSource(path="photo.jpg"), alt="photo")

# after
import base64
ImageBlock(source=Base64Source(data=base64.b64encode(open("photo.jpg","rb").read()).decode(), media_type="image/jpeg"), alt="photo")
Defensive patterns

Strategy: type-guard

Validate before calling

from agentscope.message import URLSource, Base64Source
assert isinstance(block.source, (URLSource, Base64Source))

Type guard

def is_openai_image_source(src) -> bool:
    return isinstance(src, (URLSource, Base64Source))

Try / catch

try:
    formatter.format(msgs)
except ValueError as e:
    if "Unsupported image source type" in str(e):
        block.source = to_base64_source(path, "image/png")
        formatted = formatter.format(msgs)
    else:
        raise

Prevention

When it happens

Trigger: Passing an ImageBlock with a source that is not URLSource/Base64Source — e.g. LocalFileSource, bytes, or a plain path string — to OpenAIChatFormatter.format().

Common situations: Building image messages from local file paths; custom source classes added in forks; refactors that changed how sources are created.

Related errors


AI-assisted analysis of agentscope-ai/agentscope@e90f1c7592 (2026-08-28). Data as JSON: /api/errors/0c393444e11df363. Report an issue: GitHub.