{"record":{"id":"40b32ec31238e97f","repo":"HKUDS/Vibe-Trading","slug":"unsupported-data-url-mime-type-mime","errorCode":null,"errorMessage":"unsupported data URL MIME type: {mime}","messagePattern":"unsupported data URL MIME type: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/utils/media_decode.py","lineNumber":51,"sourceCode":"        data_url: A ``data:<mime>;base64,...`` URL.\n        output_dir: Directory where the decoded file should be written.\n        max_bytes: Optional maximum decoded byte length. ``0`` disables the\n            limit.\n\n    Returns:\n        The path of the decoded file.\n\n    Raises:\n        FileSizeExceeded: If decoded data exceeds ``max_bytes``.\n        ValueError: If the URL is malformed or uses an unsupported MIME type.\n    \"\"\"\n    match = _DATA_URL_RE.match(data_url)\n    if not match:\n        raise ValueError(\"expected data:<mime>;base64,<payload>\")\n    mime = match.group(1).strip().lower()\n    ext = _EXT_BY_MIME.get(mime)\n    if not ext:\n        raise ValueError(f\"unsupported data URL MIME type: {mime}\")\n\n    payload = match.group(3).strip()\n    try:\n        decoded = base64.b64decode(payload, validate=True)\n    except (binascii.Error, ValueError) as exc:\n        raise ValueError(\"invalid base64 payload\") from exc\n\n    if max_bytes and len(decoded) > max_bytes:\n        raise FileSizeExceeded(f\"decoded media exceeds {max_bytes} bytes\")\n\n    output_dir.mkdir(parents=True, exist_ok=True)\n    path = output_dir / f\"{uuid.uuid4().hex}{ext}\"\n    path.write_bytes(decoded)\n    return path\n","sourceCodeStart":33,"sourceCodeEnd":66,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/utils/media_decode.py#L33-L66","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\npath = save_base64_data_url(\"data:image/tiff;base64,...\", out_dir)\n\n# after\npath = save_base64_data_url(\"data:image/png;base64,...\", out_dir)  # convert to PNG first","handlingStrategy":"type-guard","validationCode":"from agent.src.utils.media_decode import _EXT_BY_MIME\n\ndef has_supported_mime(data_url: str) -> bool:\n    m = _DATA_URL_RE.match(data_url) if _DATA_URL_RE.match(data_url) else None\n    return bool(m and m.group(1).strip().lower() in _EXT_BY_MIME)","typeGuard":"def is_supported_mime(data_url: str) -> bool:\n    import re\n    m = re.match(r\"^data:([^;,]+);base64,\", data_url.strip(), re.I)\n    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\"})","tryCatchPattern":"try:\n    path = save_base64_data_url(data_url, out_dir)\nexcept ValueError as e:\n    if str(e).startswith(\"unsupported data URL MIME type\"):\n        return reject_attachment(f\"use a supported type: {sorted(_EXT_BY_MIME)}\")\n    raise","preventionTips":["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"],"tags":["mime-type","media","data-url","allowlist"],"backgroundTag":"unsupported-mime-type","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}