{"record":{"id":"9080c9675b3d1f96","repo":"sgl-project/sglang","slug":"path-duration-seconds-must-be-a-number","errorCode":null,"errorMessage":"{path}.duration_seconds must be a number","messagePattern":"(.+?)\\.duration_seconds must be a number","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/minimax_h3/request_validation.py","lineNumber":124,"sourceCode":"    ):\n        raise ValueError(\n            f\"{path}.aspect_ratio for task {profile.task!r} must be 'auto' or \"\n            f\"one of {list(MINIMAX_H3_FINITE_ASPECT_RATIOS)!r}, got \"\n            f\"{aspect_ratio!r}\"\n        )\n    if not has_duration:\n        if not profile.duration_from_audio_reference:\n            raise ValueError(f\"{path}.duration_seconds is required\")\n        # ref2va: duration may derive from a reference audio; the\n        # audio-condition presence is enforced after conditions validate.\n    out: dict[str, Any] = {\n        \"short_edge\": short_edge,\n        \"aspect_ratio\": aspect_ratio,\n    }\n    if has_duration:\n        duration = target[\"duration_seconds\"]\n        if isinstance(duration, bool) or not isinstance(duration, (int, float)):\n            raise ValueError(f\"{path}.duration_seconds must be a number\")\n        if duration <= 0:\n            raise ValueError(f\"{path}.duration_seconds must be positive\")\n        if not (\n            MINIMAX_H3_MIN_DURATION_SECONDS\n            <= float(duration)\n            <= MINIMAX_H3_MAX_DURATION_SECONDS\n        ):\n            raise ValueError(\n                f\"{path}.duration_seconds must be in \"\n                f\"[{MINIMAX_H3_MIN_DURATION_SECONDS:g}, \"\n                f\"{MINIMAX_H3_MAX_DURATION_SECONDS:g}], got {duration}\"\n            )\n        out[\"duration_seconds\"] = float(duration)\n    return out\n\n\ndef _validate_conditions(\n    conditions: Any,","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/minimax_h3/request_validation.py#L106-L142","documentation":"duration_seconds was provided but is not a number — it is a string, None-as-sentinel, list, or a bool (bools are explicitly rejected even though isinstance(bool, int)).","triggerScenarios":"Passing duration_seconds=\"6\" (JSON string from user input) or True/False.","commonSituations":"Forwarding untyped form/API input; JSON where the client serialized the number as a string; configuration systems that coerce values to strings.","solutions":["Coerce to float/int before submission: float(user_value)","Reject bools explicitly at the client boundary","Validate with a numeric type guard before calling the API"],"exampleFix":"// before\n{\"duration_seconds\": \"6\"}\n// after\n{\"duration_seconds\": 6}","handlingStrategy":"type-guard","validationCode":"d = target.get('duration_seconds')\nif d is not None and (isinstance(d, bool) or not isinstance(d, (int, float))):\n    target['duration_seconds'] = float(str(d))  # or reject","typeGuard":"def is_numeric_duration(v) -> bool:\n    return not isinstance(v, bool) and isinstance(v, (int, float))","tryCatchPattern":null,"preventionTips":["Coerce string inputs to float at the API boundary","Never let raw form strings reach the request"],"tags":["minimax-h3","type-mismatch","duration"],"backgroundTag":"type-validation-failed","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}