{"record":{"id":"75b0b03423dbda63","repo":"sgl-project/sglang","slug":"kind-transition-must-be-a-map","errorCode":null,"errorMessage":"{kind} transition must be a map","messagePattern":"(.+?) transition must be a map","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/realtime/control_signals.py","lineNumber":124,"sourceCode":"        mode=\"script\",\n        payload=validate_script_payload(payload),\n    )\n\n\ndef _control_state_transitions_from_event_payload(\n    payload: dict[str, Any],\n    *,\n    event_id: int | None,\n    kind: str,\n    normalize_state_payload: ControlStatePayloadNormalizer,\n) -> list[ControlStateTransition]:\n    transitions = payload.get(\"transitions\")\n    if not isinstance(transitions, list):\n        raise ValueError(f\"{kind} state payload requires transitions\")\n    result = []\n    for transition in transitions:\n        if not isinstance(transition, dict):\n            raise ValueError(f\"{kind} transition must be a map\")\n        actions = transition.get(\"actions\")\n        if not isinstance(actions, list):\n            raise ValueError(f\"{kind} transition actions must be a list\")\n        timestamp_ms = transition.get(\"client_ts_ms\")\n        if timestamp_ms is not None:\n            timestamp_ms = int(timestamp_ms)\n        result.append(\n            ControlStateTransition(\n                payload=normalize_state_payload(actions),\n                seq_id=event_id,\n                timestamp_ms=timestamp_ms,\n            )\n        )\n    return result\n\n\nclass ControlSignalQueue:\n    \"\"\"FIFO storage for discrete realtime control signals","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/realtime/control_signals.py#L106-L142","documentation":"Raised while parsing a realtime control event's transitions list: each element of 'transitions' must be a JSON object (map), e.g. {'actions': [...], 'client_ts_ms': ...}. A bare string, number, list, or null element triggers this.","triggerScenarios":"parse_control_event_payload with transitions like [\"mute\"] or [[\"mute\"]] instead of [{\"actions\": [\"mute\"]}].","commonSituations":"Clients abbreviating transitions to plain action strings; mismatched protocol versions where transitions were previously strings.","solutions":["Wrap each transition in an object with an 'actions' list","Validate each transitions[i] is a dict before sending"],"exampleFix":"// before\n{\"transitions\": [\"mute\", \"unmute\"]}\n// after\n{\"transitions\": [{\"actions\": [\"mute\"]}, {\"actions\": [\"unmute\"]}]}","handlingStrategy":"validation","validationCode":"assert all(isinstance(t, dict) and isinstance(t.get(\"actions\"), list) for t in transitions)","typeGuard":"def transitions_valid(transitions: list) -> bool:\n    return all(isinstance(t, dict) for t in transitions)","tryCatchPattern":null,"preventionTips":["Always emit transitions as objects with an 'actions' list","Add contract tests shared between client and server for the control protocol"],"tags":["realtime","control-events","schema","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}