FoundationAgents/OpenManus · error · ValueError
Unsupported image format: {image}
Error message
Unsupported image format: {image} What it means
Raised by LLM.ask_with_images() when an element of the images argument is neither a string (treated as a URL or data-URI), nor a dict with a "url" key, nor a dict with an "image_url" key. Any other type — bytes, PIL objects, numpy arrays, file paths to local files without a data: scheme — is rejected because it cannot be mapped to the OpenAI image_url content-part shape.
Source
Thrown at app/llm.py:556
[{"type": "text", "text": content}]
if isinstance(content, str)
else content
if isinstance(content, list)
else []
)
# Add images to content
for image in images:
if isinstance(image, str):
multimodal_content.append(
{"type": "image_url", "image_url": {"url": image}}
)
elif isinstance(image, dict) and "url" in image:
multimodal_content.append({"type": "image_url", "image_url": image})
elif isinstance(image, dict) and "image_url" in image:
multimodal_content.append(image)
else:
raise ValueError(f"Unsupported image format: {image}")
# Update the message with multimodal content
last_message["content"] = multimodal_content
# Add system messages if provided
if system_msgs:
all_messages = (
self.format_messages(system_msgs, supports_images=True)
+ formatted_messages
)
else:
all_messages = formatted_messages
# Calculate tokens and check limits
input_tokens = self.count_message_tokens(all_messages)
if not self.check_token_limit(input_tokens):
raise TokenLimitExceeded(self.get_limit_error_message(input_tokens))
View on GitHub (pinned to 52a13f2a57)
Solutions
- Convert local images to a data URI string: "data:image/png;base64," + base64.b64encode(open(p,"rb").read()).decode()
- Pass dicts in the exact shapes: {"url": "..."} or {"image_url": {"url": "..."}}
- For hosted images, pass the public https URL string directly
Example fix
# before
images = [open("chart.png", "rb").read()] # bytes -> ValueError
# after
import base64
images = ["data:image/png;base64," + base64.b64encode(open("chart.png", "rb").read()).decode()] Defensive patterns
Strategy: type-guard
Validate before calling
def is_valid_image(image: object) -> bool:
if isinstance(image, str):
return True
if isinstance(image, dict):
return "url" in image or "image_url" in image
return False Type guard
from typing import TypeGuard, Any
def is_supported_image(image: Any) -> TypeGuard[str | dict]:
return (
isinstance(image, str)
or (isinstance(image, dict) and ("url" in image or "image_url" in image))
) Prevention
- Encode local files to data URIs yourself; never pass raw bytes or PIL objects
- Use exactly the shapes str | {'url': ...} | {'image_url': ...}
- Validate the images list in one place (a helper) so all call sites share the guard
When it happens
Trigger: Passing images=[open("x.png","rb").read()] (bytes), images=[PIL.Image.open(...)], images=[{"src": "data:image/png;base64,..."}] (wrong key name), or a plain local path string that is fine syntactically but will fail at the API — only the three accepted shapes pass the guard.
Common situations: Loading images as bytes or PIL objects and assuming the client encodes them; using "src" or "data" keys instead of "url"; forgetting to base64-encode local files into a data URI string.
Related errors
- Model {self.model} does not support images. Use a model from
- The last message must be from the user to attach images
- Invalid tool_choice: {tool_choice}
- Server URL is required for SSE connection
- Command is required for stdio connection
AI-assisted analysis of FoundationAgents/OpenManus@52a13f2a57 (2026-08-15).
Data as JSON: /api/errors/c2ed0a4b44646f9a.
Report an issue: GitHub.