{"record":{"id":"0a504668a839645c","repo":"PaddlePaddle/PaddleOCR","slug":"invalid-data-url-expected-a-comma-after-the-mime","errorCode":null,"errorMessage":"Invalid data URL: expected a comma after the MIME type.","messagePattern":"Invalid data URL: expected a comma after the MIME type\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mcp_server/paddleocr_mcp/utils.py","lineNumber":41,"sourceCode":"\n\ndef is_url(value: str) -> bool:\n    if not (value.startswith(\"http://\") or value.startswith(\"https://\")):\n        return False\n\n    result = urlparse(value)\n    return all([result.scheme, result.netloc]) and result.scheme in (\"http\", \"https\")\n\n\ndef is_base64(value: str) -> bool:\n    pattern = r\"^[A-Za-z0-9+/]+={0,2}$\"\n    return bool(re.fullmatch(pattern, value))\n\n\ndef extract_base64_payload(input_data: str) -> str:\n    if input_data.startswith(\"data:\"):\n        if \",\" not in input_data:\n            raise ValueError(\"Invalid data URL: expected a comma after the MIME type.\")\n        return input_data.split(\",\", 1)[1]\n    return input_data\n\n\ndef decode_base64_payload(payload: str) -> bytes:\n    try:\n        return base64.b64decode(payload, validate=True)\n    except Exception as e:\n        raise ValueError(\n            f\"Invalid Base64 input: {e}. \"\n            \"Ensure the string is complete and correctly padded.\"\n        ) from e\n\n\ndef infer_file_type_from_bytes(data: bytes) -> Optional[str]:\n    import puremagic\n\n    mime = puremagic.from_string(data, mime=True)","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/mcp_server/paddleocr_mcp/utils.py#L23-L59","documentation":"ValueError from extract_base64_payload in paddleocr_mcp/utils.py when an input starts with `data:` but contains no comma. Data URLs must look like `data:<mime>;base64,<payload>`; the function splits on the first comma, so a missing comma means the MIME header was never terminated.","triggerScenarios":"MCP client sends `data:image/png;base64` (payload omitted), `data:image/png` (no parameters and no payload), or a truncated paste where the comma was cut off.","commonSituations":"Template string built by concatenation that forgets the ',' separator; client-side truncation of long base64 strings at a fixed buffer size; LLM tool callers emitting malformed data URLs.","solutions":["Send a well-formed data URL: `data:image/png;base64,<payload>` with the comma present.","Or send the bare base64 string without the `data:` prefix — extract_base64_payload passes it through unchanged.","Build data URLs with a helper (f\"data:{mime};base64,{b64}\") instead of string concatenation."],"exampleFix":"// before\nawait tool.ocr(\"data:image/png;base64\")\n\n// after\nb64 = base64.b64encode(png_bytes).decode()\nawait tool.ocr(f\"data:image/png;base64,{b64}\")","handlingStrategy":"validation","validationCode":"def data_url_well_formed(s: str) -> bool:\n    if not s.startswith(\"data:\"):\n        return True  # bare base64 passes through\n    return \",\" in s","typeGuard":"def is_parseable_data_url(value: object) -> bool:\n    return isinstance(value, str) and (not value.startswith(\"data:\") or \",\" in value)","tryCatchPattern":"try:\n    payload = extract_base64_payload(user_input)\nexcept ValueError as e:\n    if \"comma after the MIME type\" in str(e):\n        raise ValueError(\n            \"expected 'data:<mime>;base64,<payload>' or a bare base64 string\"\n        ) from e\n    raise","preventionTips":["Build data URLs with f-strings that visibly include the comma: f\"data:{mime};base64,{b64}\".","Validate client-side that any 'data:' string contains ',' before sending to the MCP tool.","Prefer sending bare base64 without the data: prefix when the API accepts it."],"tags":["python","mcp","data-url","base64","validation"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}