{"record":{"id":"4fa14650be4fa908","repo":"sgl-project/sglang","slug":"seq-must-be-positive-got-seq","errorCode":null,"errorMessage":"seq must be positive, got {seq}","messagePattern":"seq must be positive, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/multimodal/processors/dots_note_omni.py","lineNumber":49,"sourceCode":"from sglang.srt.utils import VideoData, get_video_bytes\n\nlogger = logging.getLogger(__name__)\n\n_VIDEO_TOKEN_RE = re.compile(r\"(<image_\\d+>|<audio_\\d+>)\")\n_EXPANDED_VIDEO_MEDIA_RE = re.compile(\n    r\"<\\|sglang_dots_video_(?P<video>\\d+)_(?P<modality>image|audio)_(?P<item>\\d+)\\|>\"\n)\n\n\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),","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/multimodal/processors/dots_note_omni.py#L31-L67","documentation":"Raised by _build_video_cfg in the Dots Note Omni multimodal processor when the seq parameter is zero or negative. seq bounds the total sequence budget for a video request; a non-positive value makes the derived seq_length meaningless, so the processor rejects it before building the config dict.","triggerScenarios":"Calling preprocess_dots_video (directly or via process_mm_data_async) with seq<=0, e.g. passing video_config={\"seq\": 0} in the request, or omitting it while a wrapper computes seq as context_len - max_tokens and underflows to <=0.","commonSituations":"Users compute seq = model_context_len - max_new_tokens and pass a negative value when max_new_tokens exceeds context length; or they copy a config where seq is set per-model and use 0/None coerced to 0.","solutions":["Check that seq (video_config 'seq', default 131072) is > 0 before sending the request","If computing seq from context window, ensure max_new_tokens < context_len so the subtraction stays positive","Validate in the client: raise early with your own message instead of the server-side ValueError"],"exampleFix":"// before\nvideo_config = {\"seq\": context_len - max_new_tokens}  # can be <= 0\n// after\nvideo_config = {\"seq\": max(1, context_len - max_new_tokens)}\nassert video_config[\"seq\"] > 0","handlingStrategy":"validation","validationCode":"cfg = request.get('video_config') or {}\nseq = cfg.get('seq', 131072)\nassert isinstance(seq, int) and seq > 0, f'seq must be positive, got {seq}'","typeGuard":"def valid_seq(cfg: dict) -> bool:\n    seq = cfg.get('seq', 131072)\n    return isinstance(seq, int) and not isinstance(seq, bool) and seq > 0","tryCatchPattern":null,"preventionTips":["Compute seq from context budget with a max(1, ...) clamp","Validate video_config keys/types client-side before sending"],"tags":["multimodal","video","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"}