{"record":{"id":"a9b0cda7da6c8fa2","repo":"sgl-project/sglang","slug":"cosmos3-requires-num-frames-action-horizon-1","errorCode":null,"errorMessage":"Cosmos3 requires num_frames == action_horizon + 1, got num_frames={num_frames}, action_horizon={action_horizon}","messagePattern":"Cosmos3 requires num_frames == action_horizon \\+ 1, got num_frames=(.+?), action_horizon=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/entrypoints/action/cosmos3.py","lineNumber":156,"sourceCode":"            \"Cosmos3 forward_dynamics produces video; use /v1/videos instead\"\n        )\n    if action_mode not in (\"policy\", \"inverse_dynamics\"):\n        raise ValueError(\n            \"Cosmos3 action endpoint supports action_mode='policy' or \"\n            \"'inverse_dynamics'\"\n        )\n\n    action_horizon = options.get(\"action_horizon\")\n    num_frames = options.get(\"num_frames\")\n    if action_horizon is None and num_frames is None:\n        action_horizon = 16\n    if action_horizon is not None:\n        action_horizon = int(action_horizon)\n        if action_horizon <= 0:\n            raise ValueError(\"action_horizon must be a positive integer\")\n        expected_num_frames = action_horizon + 1\n        if num_frames is not None and int(num_frames) != expected_num_frames:\n            raise ValueError(\n                \"Cosmos3 requires num_frames == action_horizon + 1, got \"\n                f\"num_frames={num_frames}, action_horizon={action_horizon}\"\n            )\n        num_frames = expected_num_frames\n    else:\n        num_frames = int(num_frames)\n        if num_frames <= 1:\n            raise ValueError(\"Cosmos3 action num_frames must be greater than 1\")\n    if (num_frames - 1) % 4 != 0:\n        raise ValueError(\n            \"Cosmos3 action_horizon must be divisible by 4 so num_frames \"\n            \"is compatible with the temporal VAE\"\n        )\n\n    images = _images_from_observation(observation)\n    video_path = options.get(\"video_path\") or observation.get(\"video\")\n    if action_mode == \"policy\" and not images:\n        raise ValueError(\"Cosmos3 policy input requires an observation image\")","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/entrypoints/action/cosmos3.py#L138-L174","documentation":"When both action_horizon and num_frames are supplied to the Cosmos3 action endpoint, they must satisfy num_frames == action_horizon + 1 (the model generates one action per future frame beyond the conditioning frame). Passing an inconsistent pair is rejected before request construction.","triggerScenarios":"action_horizon=16 with num_frames=16; action_horizon=8 with num_frames=32 — any pair where num_frames != action_horizon + 1.","commonSituations":"Copy-pasting a video-generation config (where num_frames is set independently) into an action request; stale num_frames after tuning action_horizon.","solutions":["Set num_frames = action_horizon + 1, or omit num_frames entirely (it is derived from action_horizon)","If you must keep num_frames, derive action_horizon = num_frames - 1 and ensure it is positive and divisible by 4"],"exampleFix":"# before\n{\"parameters\": {\"action_horizon\": 16, \"num_frames\": 16}}\n# after\n{\"parameters\": {\"action_horizon\": 16, \"num_frames\": 17}}","handlingStrategy":"validation","validationCode":"h, nf = params.get('action_horizon'), params.get('num_frames')\nif h is not None and nf is not None:\n    assert int(nf) == int(h) + 1, 'num_frames must equal action_horizon + 1'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set only action_horizon and let the server derive num_frames","Never copy num_frames from video-generation configs into action requests"],"tags":["cosmos3","num-frames","action-horizon","constraint-violation"],"backgroundTag":"inconsistent-parameter-constraint","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}