{"record":{"id":"20b3592c62daf17d","repo":"sgl-project/sglang","slug":"audio-cap-must-be-non-negative-got-audio-cap","errorCode":null,"errorMessage":"audio_cap must be non-negative, got {audio_cap}","messagePattern":"audio_cap must be non-negative, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/multimodal/processors/dots_note_omni.py","lineNumber":58,"sourceCode":"\ndef _build_video_cfg(\n    *,\n    seq: int,\n    audio_cap: float,\n    audio_sr: int,\n    max_new_tokens: int,\n) -> dict[str, Any]:\n    if seq <= 0:\n        raise ValueError(f\"seq must be positive, got {seq}\")\n    if max_new_tokens < 0:\n        raise ValueError(f\"max_new_tokens must be non-negative, got {max_new_tokens}\")\n    if max_new_tokens >= seq:\n        raise ValueError(\n            \"max_new_tokens must leave room for input: \"\n            f\"max_new_tokens={max_new_tokens}, seq={seq}\"\n        )\n    if audio_cap < 0:\n        raise ValueError(f\"audio_cap must be non-negative, got {audio_cap}\")\n    if audio_sr <= 0:\n        raise ValueError(f\"audio_sr must be positive, got {audio_sr}\")\n\n    return {\n        \"process_audio\": audio_cap > 0,\n        \"seq_length\": seq - max_new_tokens,\n        \"reserve_interleave\": True,\n        \"audio_token_ratio_cap\": float(audio_cap),\n        \"audio_sample_rate\": int(audio_sr),\n        \"video_jpeg_quality\": int(os.environ.get(\"XHS_VIDEO_JPEG_QUALITY\", \"85\")),\n    }\n\n\ndef _video_payload(raw_video) -> tuple[bytes, str]:\n    if isinstance(raw_video, VideoData):\n        raw_video = raw_video.url\n    raw_url = raw_video.get(\"url\") if isinstance(raw_video, dict) else raw_video\n    video_bytes = get_video_bytes(raw_url)","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/multimodal/processors/dots_note_omni.py#L40-L76","documentation":"Raised by _build_video_cfg when audio_cap is negative. audio_cap caps the audio token ratio (process_audio is enabled when audio_cap > 0); negatives are invalid and rejected before building the config.","triggerScenarios":"Passing video_config={\"audio_cap\": -1.0} (or any negative number) in a Dots Note Omni video request.","commonSituations":"Users misunderstand audio_cap as a boolean/integer flag or compute it as a difference that goes negative; the valid range is [0.0, ...) with 0 disabling audio processing.","solutions":["Set audio_cap to a non-negative float (default 1.0; 0 disables audio processing)","If computing the cap dynamically, clamp with max(0.0, value)"],"exampleFix":"// before\nvideo_config = {\"audio_cap\": tokens_audio - tokens_budget}  # negative\n// after\nvideo_config = {\"audio_cap\": max(0.0, tokens_audio - tokens_budget)}","handlingStrategy":"validation","validationCode":"cap = cfg.get('audio_cap', 1.0)\nassert isinstance(cap, (int, float)) and cap >= 0, f'audio_cap invalid: {cap}'","typeGuard":"def valid_audio_cap(cfg: dict) -> bool:\n    cap = cfg.get('audio_cap', 1.0)\n    return isinstance(cap, (int, float)) and not isinstance(cap, bool) and cap >= 0","tryCatchPattern":null,"preventionTips":["Remember audio_cap is a non-negative ratio; 0 disables audio","Clamp dynamic values: max(0.0, computed_cap)"],"tags":["multimodal","audio","config-validation","valueerror"],"backgroundTag":"invalid-config-parameter","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}