sgl-project/sglang · error · ValueError

action_horizon must be a positive integer

Error message

action_horizon must be a positive integer

What it means

Cosmos3 requires action_horizon to be a positive integer (>0) when provided (defaulting to 16 if neither action_horizon nor num_frames is given). The value is coerced with int() before validation. Zero or negative horizons are meaningless for action chunk generation and are rejected up front.

Source

Thrown at python/sglang/multimodal_gen/runtime/entrypoints/action/cosmos3.py:153

    action_mode = str(options.get("action_mode", "policy")).strip().lower()
    if action_mode == "forward_dynamics":
        raise ValueError(
            "Cosmos3 forward_dynamics produces video; use /v1/videos instead"
        )
    if action_mode not in ("policy", "inverse_dynamics"):
        raise ValueError(
            "Cosmos3 action endpoint supports action_mode='policy' or "
            "'inverse_dynamics'"
        )

    action_horizon = options.get("action_horizon")
    num_frames = options.get("num_frames")
    if action_horizon is None and num_frames is None:
        action_horizon = 16
    if action_horizon is not None:
        action_horizon = int(action_horizon)
        if action_horizon <= 0:
            raise ValueError("action_horizon must be a positive integer")
        expected_num_frames = action_horizon + 1
        if num_frames is not None and int(num_frames) != expected_num_frames:
            raise ValueError(
                "Cosmos3 requires num_frames == action_horizon + 1, got "
                f"num_frames={num_frames}, action_horizon={action_horizon}"
            )
        num_frames = expected_num_frames
    else:
        num_frames = int(num_frames)
        if num_frames <= 1:
            raise ValueError("Cosmos3 action num_frames must be greater than 1")
    if (num_frames - 1) % 4 != 0:
        raise ValueError(
            "Cosmos3 action_horizon must be divisible by 4 so num_frames "
            "is compatible with the temporal VAE"
        )

    images = _images_from_observation(observation)

View on GitHub (pinned to 0132848349)

Solutions

  1. Set action_horizon to a positive integer (typical valid values are multiples of 4 like 16)
  2. If computing it dynamically, guard: action_horizon = max(1, computed_value)
  3. Remember the default of 16 applies only when both action_horizon and num_frames are absent

Example fix

# before
{"parameters": {"action_horizon": 0}}
# after
{"parameters": {"action_horizon": 16}}
Defensive patterns

Strategy: validation

Validate before calling

h = params.get('action_horizon')
if h is not None:
    assert int(h) > 0, 'action_horizon must be positive'

Prevention

When it happens

Trigger: Passing parameters.action_horizon=0, -4, or a value that int()-coerces to <=0 (e.g. '-1'); passing num_frames alone doesn't trigger this branch.

Common situations: Config templates defaulting numeric fields to 0; arithmetic computing horizon from a window size that collapses to 0; sending floats like 0.0.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/a59d785c01b9c5cc. Report an issue: GitHub.