HKUDS/Vibe-Trading · error · ValueError
unsupported data URL MIME type: {mime}
Error message
unsupported data URL MIME type: {mime} What it means
After the data URL structure matches, save_base64_data_url extracts the MIME type and looks it up in _EXT_BY_MIME to determine the output file extension. If the MIME type is not in the supported allowlist, the ValueError 'unsupported data URL MIME type: <mime>' is raised, because there is no known extension or sanctioned decoder for that type.
Source
Thrown at agent/src/utils/media_decode.py:51
data_url: A ``data:<mime>;base64,...`` URL.
output_dir: Directory where the decoded file should be written.
max_bytes: Optional maximum decoded byte length. ``0`` disables the
limit.
Returns:
The path of the decoded file.
Raises:
FileSizeExceeded: If decoded data exceeds ``max_bytes``.
ValueError: If the URL is malformed or uses an unsupported MIME type.
"""
match = _DATA_URL_RE.match(data_url)
if not match:
raise ValueError("expected data:<mime>;base64,<payload>")
mime = match.group(1).strip().lower()
ext = _EXT_BY_MIME.get(mime)
if not ext:
raise ValueError(f"unsupported data URL MIME type: {mime}")
payload = match.group(3).strip()
try:
decoded = base64.b64decode(payload, validate=True)
except (binascii.Error, ValueError) as exc:
raise ValueError("invalid base64 payload") from exc
if max_bytes and len(decoded) > max_bytes:
raise FileSizeExceeded(f"decoded media exceeds {max_bytes} bytes")
output_dir.mkdir(parents=True, exist_ok=True)
path = output_dir / f"{uuid.uuid4().hex}{ext}"
path.write_bytes(decoded)
return path
View on GitHub (pinned to 80ffdda44c)
Solutions
- Check _EXT_BY_MIME keys for the supported MIME allowlist and convert the media to a supported type before upload
- Re-encode the asset (e.g. tiff -> png) client-side
- If the type should be supported, extend _EXT_BY_MIME with the mime->extension mapping after security review
Example fix
# before
path = save_base64_data_url("data:image/tiff;base64,...", out_dir)
# after
path = save_base64_data_url("data:image/png;base64,...", out_dir) # convert to PNG first Defensive patterns
Strategy: type-guard
Validate before calling
from agent.src.utils.media_decode import _EXT_BY_MIME
def has_supported_mime(data_url: str) -> bool:
m = _DATA_URL_RE.match(data_url) if _DATA_URL_RE.match(data_url) else None
return bool(m and m.group(1).strip().lower() in _EXT_BY_MIME) Type guard
def is_supported_mime(data_url: str) -> bool:
import re
m = re.match(r"^data:([^;,]+);base64,", data_url.strip(), re.I)
return bool(m and m.group(1).lower() in {"image/png", "image/jpeg", "image/gif", "audio/mpeg", "audio/wav", "audio/webm", "video/mp4", "video/webm"}) Try / catch
try:
path = save_base64_data_url(data_url, out_dir)
except ValueError as e:
if str(e).startswith("unsupported data URL MIME type"):
return reject_attachment(f"use a supported type: {sorted(_EXT_BY_MIME)}")
raise Prevention
- Constrain uploads client-side to a fixed accept= list matching _EXT_BY_MIME
- Expose the supported MIME list via an API endpoint so clients stay in sync
- Never add SVG or HTML to the allowlist without sanitization review
When it happens
Trigger: Passing data URLs with types like 'application/pdf', 'image/tiff', 'video/x-matroska', or even typos like 'image/jpg' (vs 'image/jpeg') when _EXT_BY_MIME only contains allowlisted entries such as image/png, image/jpeg, image/gif, audio/*, etc.
Common situations: Client-side MIME sniffing producing exotic types, uppercase or aliased MIME names, a new media format the allowlist predates, or copy-paste of SVG ('image/svg+xml') which is intentionally excluded for security.
Related errors
- expected data:<mime>;base64,<payload>
- unsafe media URL: {error}
- CDN upload response missing x-encrypted-param header; status
- Live-broker MCP server '{server_key}' may not use a wildcard
- invalid base64 payload
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/40b32ec31238e97f.
Report an issue: GitHub.