sgl-project/sglang · error · ValueError
Unrecognized image input, support local path, http url, base
Error message
Unrecognized image input, support local path, http url, base64 and PIL.Image, got {image} What it means
Raised by fetch_image when the image argument can't be opened through any supported route (local path via Image.open, bytes via BytesIO, base64, or PIL.Image) and image_obj ends up None. The message echoes the offending input value.
Source
Thrown at python/sglang/srt/multimodal/processors/mimo_v2.py:1468
image_obj = image
elif isinstance(image, str):
if image.startswith("http://") or image.startswith("https://"):
with BytesIO(download_remote_media(image, timeout=3)) as bio:
image_obj = copy.deepcopy(Image.open(bio))
elif image.startswith("file://"):
image_obj = Image.open(image[7:])
elif image.startswith("data:image"):
if "base64," in image:
_, base64_data = image.split("base64,", 1)
data = base64.b64decode(base64_data)
with BytesIO(data) as bio:
image_obj = copy.deepcopy(Image.open(bio))
else:
image_obj = Image.open(image)
else:
image_obj = Image.open(BytesIO(image))
if image_obj is None:
raise ValueError(
f"Unrecognized image input, support local path, http url, base64 and PIL.Image, got {image}"
)
image = cls.to_rgb(image_obj)
return image
class MiMoV2Processor(BaseMultimodalProcessor):
models = [MiMoV2ForCausalLM]
@staticmethod
def _normalize_config_dict(config, name: str) -> dict:
if config is None:
return {}
if isinstance(config, dict):
return config
if hasattr(config, "to_dict"):
return config.to_dict()
raise ValueError(f"{name} must be a dict-like config, got {type(config)}")View on GitHub (pinned to 0132848349)
Solutions
- Send a plain base64 string (strip 'data:image/...;base64,' prefixes) or raw image bytes
- Verify the image opens locally: PIL.Image.open(BytesIO(b64decode(s))).verify()
- For local files, pass the filesystem path string
Example fix
# before
img_b64 = 'data:image/png;base64,iVBOR...' # prefix not stripped
# after
import base64
img_b64 = 'iVBOR...' # or base64.b64encode(open('x.png','rb').read()).decode() Defensive patterns
Strategy: validation
Validate before calling
from io import BytesIO
from PIL import Image
import base64, re
def is_loadable_image(s):
try:
raw = base64.b64decode(re.sub(r'^data:[^;]+;base64,', '', s))
Image.open(BytesIO(raw)).verify()
return True
except Exception:
return False Type guard
def is_recognized_image_input(x) -> bool:
return (isinstance(x, (str, bytes)) or isinstance(x, Image.Image)) and \
(not isinstance(x, str) or not x.startswith('data:')) Try / catch
try:
im = MiMoProcessor.fetch_image(image)
except ValueError as e:
if 'Unrecognized image input' in str(e):
return error_response(400, 'send base64 without data-URI prefix, raw bytes, a path, or a URL')
raise Prevention
- Strip data-URI prefixes before sending base64
- Verify bytes decode with PIL before upload
- Never send None or file handles as image payloads
When it happens
Trigger: Calling process_image/fetch_image with a value that falls through all branches — e.g. a malformed base64 string that decodes to nothing openable, a file-like object, an int/None, or a corrupt byte payload that Image.open silently fails on in this flow.
Common situations: Bad base64 (missing padding, data-URI prefix not stripped); corrupt image bytes; clients sending file handles instead of bytes; None values slipping through request parsing.
Related errors
- image payload requires b64_json
- Error while loading data {data_str}: {e}
- An exception occurred while loading {modality.name} data at
- absolute aspect ratio must be smaller than 200, got {max(hei
- Unsupported image type: {type(img)}. Expected torch.Tensor o
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/3f10ef4bb86a5e6e.
Report an issue: GitHub.