{"record":{"id":"cfefa306da9c787e","repo":"sgl-project/sglang","slug":"image-payload-requires-b64-json","errorCode":null,"errorMessage":"image payload requires b64_json","messagePattern":"image payload requires b64_json","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/entrypoints/action/protocol.py","lineNumber":80,"sourceCode":"    return obj\n\n\ndef pack_msgpack(payload: Any) -> bytes:\n    import msgpack\n\n    return msgpack.packb(payload, default=pack_numpy_payload, use_bin_type=True)\n\n\ndef unpack_msgpack(payload: bytes) -> Any:\n    import msgpack\n\n    return msgpack.unpackb(payload, object_hook=unpack_numpy_payload, raw=False)\n\n\ndef _decode_b64_image(payload: dict[str, Any]) -> Image.Image:\n    data = payload.get(\"b64_json\") or payload.get(\"base64\")\n    if not data:\n        raise ValueError(\"image payload requires b64_json\")\n    if isinstance(data, str) and \",\" in data and data.startswith(\"data:\"):\n        data = data.split(\",\", 1)[1]\n    return Image.open(io.BytesIO(base64.b64decode(data))).convert(\"RGB\")\n\n\ndef _decode_tensor_payload(payload: dict[str, Any]) -> Any:\n    values = payload.get(\"values\")\n    if values is None:\n        values = payload.get(\"data\")\n    if values is None:\n        return payload\n    dtype = payload.get(\"dtype\")\n    array = np.asarray(values, dtype=np.dtype(dtype) if dtype else None)\n    shape = payload.get(\"shape\")\n    if shape is not None:\n        array = array.reshape(tuple(shape))\n    return array\n","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/entrypoints/action/protocol.py#L62-L98","documentation":"The action endpoint's image decoder expects an embedded image as base64 in the b64_json (or base64) key of an image payload dict. If both keys are missing/empty/falsy, _decode_b64_image raises before attempting decode. Data-URI prefixed strings (data:image/...;base64,...) are handled automatically.","triggerScenarios":"Sending an image object like {\"url\": \"...\"} or {\"format\": \"png\"} without b64_json/base64 content; sending b64_json: \"\" or null.","commonSituations":"Client sends a URL-style image object where embedded bytes were expected; upstream base64 encoding failed producing an empty string; key name mismatch between client and server versions.","solutions":["Populate b64_json with the full base64 of the image bytes (data-URI prefix is fine)","If you have a file/URL, pass the path/URL in the image field instead of an embedded payload object","Verify base64.b64encode(open(p,'rb').read()).decode() is non-empty before sending"],"exampleFix":"# before\n{\"image\": {\"format\": \"png\"}}\n# after\n{\"image\": {\"b64_json\": base64.b64encode(open('obs.png','rb').read()).decode()}}","handlingStrategy":"validation","validationCode":"import base64\ndef embedded_image_ok(img):\n    if isinstance(img, dict):\n        d = img.get('b64_json') or img.get('base64')\n        return bool(d) and len(base64.b64decode(d.split(',')[-1])) > 0\n    return True  # path/URL form","typeGuard":"def has_b64_payload(img) -> bool:\n    return not isinstance(img, dict) or bool(img.get('b64_json') or img.get('base64'))","tryCatchPattern":null,"preventionTips":["Encode with base64.b64encode(open(path,'rb').read()).decode() and assert non-empty","Use URL/path image fields for remote images instead of embedding"],"tags":["image-payload","base64","input-validation","action-endpoint"],"backgroundTag":"missing-base64-payload","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}