{"record":{"id":"0c393444e11df363","repo":"agentscope-ai/agentscope","slug":"unsupported-image-source-type-type-source-0c3934","errorCode":null,"errorMessage":"Unsupported image source type: {type(source)}","messagePattern":"Unsupported image source type: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/agentscope/formatter/_openai_formatter.py","lineNumber":115,"sourceCode":"                A dictionary with ``\"type\": \"image_url\"`` in OpenAI format.\n        \"\"\"\n        if isinstance(source, Base64Source):\n            url = f\"data:{source.media_type};base64,{source.data}\"\n\n        elif isinstance(source, URLSource):\n            url_str = str(source.url)\n            if url_str.startswith(\"file://\"):\n                # Local file — read and encode as base64 data URI\n                local_path = url_str.removeprefix(\"file://\")\n                with open(local_path, \"rb\") as f:\n                    encoded = base64.b64encode(f.read()).decode(\"utf-8\")\n                url = f\"data:{source.media_type};base64,{encoded}\"\n            else:\n                # Remote URL — pass through as-is\n                url = url_str\n\n        else:\n            raise ValueError(f\"Unsupported image source type: {type(source)}\")\n\n        return {\n            \"type\": \"image_url\",\n            \"image_url\": {\"url\": url},\n        }\n\n    @staticmethod\n    def _format_audio_source(\n        source: URLSource | Base64Source,\n    ) -> dict[str, Any]:\n        \"\"\"Convert an audio source to OpenAI input_audio format.\n\n        Local ``file://`` URLs are read from disk. Remote URLs are downloaded.\n        Only ``wav`` and ``mp3`` formats are supported by the OpenAI API.\n\n        Args:\n            source (`URLSource | Base64Source`):\n                The audio source to convert.","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/formatter/_openai_formatter.py#L97-L133","documentation":"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.","triggerScenarios":"Passing an ImageBlock with a source that is not URLSource/Base64Source — e.g. LocalFileSource, bytes, or a plain path string — to OpenAIChatFormatter.format().","commonSituations":"Building image messages from local file paths; custom source classes added in forks; refactors that changed how sources are created.","solutions":["Convert the local image to Base64Source and let the formatter emit a data: URL","Or upload/host the image and use URLSource (OpenAI fetches remote URLs)","Validate sources before formatting and downgrade unsupported image blocks to text"],"exampleFix":"# before\nImageBlock(source=LocalFileSource(path=\"photo.jpg\"), alt=\"photo\")\n\n# after\nimport base64\nImageBlock(source=Base64Source(data=base64.b64encode(open(\"photo.jpg\",\"rb\").read()).decode(), media_type=\"image/jpeg\"), alt=\"photo\")","handlingStrategy":"type-guard","validationCode":"from agentscope.message import URLSource, Base64Source\nassert isinstance(block.source, (URLSource, Base64Source))","typeGuard":"def is_openai_image_source(src) -> bool:\n    return isinstance(src, (URLSource, Base64Source))","tryCatchPattern":"try:\n    formatter.format(msgs)\nexcept ValueError as e:\n    if \"Unsupported image source type\" in str(e):\n        block.source = to_base64_source(path, \"image/png\")\n        formatted = formatter.format(msgs)\n    else:\n        raise","preventionTips":["Convert local images to Base64Source; hosted images should use URLSource so OpenAI fetches them directly","Validate blocks in a shared preprocess step across providers"],"tags":["openai","image","multimodal","formatter","agentscope"],"backgroundTag":"unsupported-media-source-type","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}