{"record":{"id":"8092f3e25f63fd56","repo":"sgl-project/sglang","slug":"invalid-audio-format-audio-file","errorCode":null,"errorMessage":"Invalid audio format: {audio_file}","messagePattern":"Invalid audio format: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/utils/common.py","lineNumber":1709,"sourceCode":"    if sr is None:\n        sr = 16000\n\n    # Normalize input: resolve URL / base64 / file:// to bytes or path\n    if isinstance(audio_file, bytes):\n        source = audio_file\n    elif isinstance(audio_file, str) and audio_file.startswith(\"data:\"):\n        source = pybase64.b64decode(audio_file.split(\",\")[1], validate=True)\n    elif isinstance(audio_file, str) and (\n        audio_file.startswith(\"http://\") or audio_file.startswith(\"https://\")\n    ):\n        timeout = int(os.getenv(\"REQUEST_TIMEOUT\", \"5\"))\n        source = download_remote_media(audio_file, timeout=timeout)\n    elif isinstance(audio_file, str) and audio_file.startswith(\"file://\"):\n        source = unquote(urlparse(audio_file).path)\n    elif isinstance(audio_file, str):\n        source = audio_file\n    else:\n        raise ValueError(f\"Invalid audio format: {audio_file}\")\n\n    from sglang.srt.multimodal.audio_from_video import (\n        decode_audio_container,\n        is_audio_container,\n    )\n\n    if isinstance(source, bytes):\n        header = source[:16]\n    else:\n        with open(source, \"rb\") as audio_stream:\n            header = audio_stream.read(16)\n\n    if is_audio_container(header):\n        return decode_audio_container(\n            source,\n            target_sr=sr,\n            mono=mono,\n        )","sourceCodeStart":1691,"sourceCodeEnd":1727,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/utils/common.py#L1691-L1727","documentation":"load_audio accepts bytes, http(s) URLs, file:// URI paths, or plain local path strings; any other type (None, int, list) hits the final else branch and raises. The message echoes the offending value to make the bad input identifiable in multimodal request logs.","triggerScenarios":"Calling load_audio(None), load_audio(123), or passing a non-str/bytes object from a chat template / request parser that failed to extract the audio field; e.g. an 'audio' key present but null in the request JSON.","commonSituations":"Clients sending {\"audio\": null} or numbers; frontend bugs forwarding the wrong JSON field; protobuf deserialization producing unexpected types.","solutions":["Validate/require the audio field in request parsing before calling load_audio","Normalize input to str/bytes: coerce or reject with a 400 at the API layer","Check for None explicitly and return a proper client error"],"exampleFix":"# before\nwav, sr = load_audio(req.get('audio'))  # None when key missing -> ValueError\n# after\nif not req.get('audio'): raise HTTPException(400, 'audio field required')\nwav, sr = load_audio(req['audio'])","handlingStrategy":"type-guard","validationCode":"if not isinstance(audio_file, (str, bytes)) or not audio_file:\n    return HTTPException(400, 'audio must be a non-empty string (url/path/base64) or bytes')\nwav, sr = load_audio(audio_file, sr=sr)","typeGuard":"def is_audio_input(v) -> bool:\n    return isinstance(v, (str, bytes)) and len(v) > 0","tryCatchPattern":"try:\n    wav, sr = load_audio(audio_file)\nexcept ValueError as e:\n    if 'Invalid audio format' in str(e):\n        return HTTPException(400, str(e))\n    raise","preventionTips":["Validate the audio field's presence and type in request schemas","Reject null/missing multimodal fields at the API boundary"],"tags":["audio","multimodal","validation","input-validation"],"backgroundTag":"invalid-argument-type","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}