sgl-project/sglang · error · ValueError

unknown action keys {bad}; allowed keys are {sorted(_SANA_WM

Error message

unknown action keys {bad}; allowed keys are {sorted(_SANA_WM_ALLOWED_ACTION_KEYS)}

What it means

Raised by parse_sana_wm_action_string when the keys part of a segment contains characters outside _SANA_WM_ALLOWED_ACTION_KEYS (after lowercasing). Only the whitelisted single-letter camera action keys are accepted; 'none' is the special empty-key form.

Source

Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/sana_wm/base.py:146

            raise ValueError(
                f"invalid action segment {segment!r}; expected '<keys>-<frames>'"
            )
        keys_part, duration = segment.rsplit("-", 1)
        if not duration.isdigit() or int(duration) <= 0:
            raise ValueError(f"invalid duration in action segment {segment!r}")

        if keys_part.lower() == "none":
            keys: list[str] = []
        else:
            bad = sorted(
                {
                    char
                    for char in keys_part.lower()
                    if char not in _SANA_WM_ALLOWED_ACTION_KEYS
                }
            )
            if bad:
                raise ValueError(
                    f"unknown action keys {bad}; allowed keys are "
                    f"{sorted(_SANA_WM_ALLOWED_ACTION_KEYS)}"
                )
            keys = sorted(set(keys_part.lower()))
        # Fresh list per frame: repeated frames must NOT alias one list object
        # (callers could mutate a frame and silently edit all its repeats).
        per_frame.extend([list(keys) for _ in range(int(duration))])
    return per_frame


def sana_wm_action_to_camera_to_world_array(
    action: str,
    *,
    translation_speed: float = _SANA_WM_BIDIRECTIONAL_DEFAULT_TRANSLATION_SPEED,
    rotation_speed_deg: float = _SANA_WM_DEFAULT_ROTATION_SPEED_DEG,
    pitch_limit_deg: float = _SANA_WM_DEFAULT_PITCH_LIMIT_DEG,
    strafe_yaw_coupling: float = 0.4,
) -> np.ndarray:

View on GitHub (pinned to 0132848349)

Solutions

  1. Use only allowed keys — check sorted(_SANA_WM_ALLOWED_ACTION_KEYS) in the module
  2. Use word 'none' (lowercase) for no-action segments
  3. Map user words to keys before building the string, e.g. {'left':'a','right':'d'}

Example fix

// before
action = 'forward-4'
// after
action = 'f-4'  # or whatever keys are in _SANA_WM_ALLOWED_ACTION_KEYS
Defensive patterns

Strategy: validation

Validate before calling

from sglang.multimodal_gen.runtime.pipelines_core.stages.model_specific_stages.sana_wm.base import _SANA_WM_ALLOWED_ACTION_KEYS as K
assert set(''.join(keys)) <= K

Type guard

def keys_allowed(keys_part: str, allowed: set[str]) -> bool:
    return keys_part.lower() == 'none' or set(keys_part.lower()) <= allowed

Prevention

When it happens

Trigger: Segments like 'xy-4' where 'x'/'y' are not allowed keys, or misspelled words like 'forward-4' (each letter 'f','o','r','w','a','d' is checked individually).

Common situations: Users writing word commands ('left','zoom') instead of the letter key shorthand; typos in key letters; LLM emitting invented keys.

Related errors


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