sgl-project/sglang · error · ValueError

{key}.position_ids is required

Error message

{key}.position_ids is required

What it means

forward() extracts per-modality position ids via _pos_ids, which accepts either a dict with key 'position_ids' or an object with a .position_ids attribute, and requires it to be present. If the given pos_info for a modality (video/audio/text) has no position_ids, the error names the missing '{key}.position_ids'.

Source

Thrown at python/sglang/multimodal_gen/runtime/models/dits/minimax_h3.py:2111

            assert self.time_embedder is not None
            return self.time_embedder(timesteps)

        grid = self.adaln_t_table.shape[0]
        position = timesteps.to(_FP32_DTYPE).clamp(0, 1) * (grid - 1)
        lower = position.floor().clamp(max=grid - 2).to(torch.long)
        fraction = (position - lower).unsqueeze(-1)
        lower_value = self.adaln_t_table.index_select(0, lower)
        upper_value = self.adaln_t_table.index_select(0, lower + 1)
        return torch.lerp(lower_value, upper_value, fraction)

    @staticmethod
    def _pos_ids(pos_info: Any, key: str) -> torch.Tensor:
        if isinstance(pos_info, dict):
            ids = pos_info.get("position_ids")
        else:
            ids = getattr(pos_info, "position_ids", None)
        if ids is None:
            raise ValueError(f"{key}.position_ids is required")
        return ids.view(-1).to(torch.long)

    @staticmethod
    def _psp_field(psp: Any, key: str, field: str) -> Any:
        if isinstance(psp, dict):
            value = psp.get(field)
        else:
            value = getattr(psp, field, None)
        if value is None:
            raise ValueError(f"{key}.{field} is required")
        return value

    @staticmethod
    def _psp_optional_field(psp: Any, field: str) -> Any:
        if isinstance(psp, dict):
            return psp.get(field)
        return getattr(psp, field, None)

View on GitHub (pinned to 0132848349)

Solutions

  1. Add a [1, S, 3]-shaped (or model-specified) integer position_ids tensor under the reported key in the dict / attribute on the object
  2. Reuse the position-id builder from the data pipeline instead of hand-crafting inputs
  3. If the modality is truly absent, omit the whole modality entry rather than passing an empty one

Example fix

# before
pos = {"video": {"grid": grid}}
# after
pos = {"video": {"position_ids": compute_video_pos_ids(grid)}}
Defensive patterns

Strategy: type-guard

Validate before calling

def has_pos_ids(pos_info) -> bool:
    ids = pos_info.get("position_ids") if isinstance(pos_info, dict) else getattr(pos_info, "position_ids", None)
    return ids is not None
assert all(has_pos_ids(v) for v in pos_inputs.values())

Type guard

def has_pos_ids(pos_info: Any) -> bool:
    if isinstance(pos_info, dict):
        return pos_info.get("position_ids") is not None
    return getattr(pos_info, "position_ids", None) is not None

Prevention

When it happens

Trigger: Calling forward with position-encoding info like {"video": {"grid": ...}} (no position_ids key) or a dataclass/namespace lacking the position_ids attribute.

Common situations: Building multimodal inputs by hand and forgetting the position_ids tensor; migrating from an older input schema where positions were derived internally; passing None fields for an optional modality that the model actually expects.

Related errors


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