sgl-project/sglang · error · ValueError

prompt event payload must be a string

Error message

prompt event payload must be a string

What it means

The LingBot world realtime adapter's sample_prompt popped the latest 'prompt' event and its payload was not a str (e.g. dict, number, or None-like non-string). The adapter enforces that prompt events carry plain string payloads.

Source

Thrown at python/sglang/multimodal_gen/runtime/entrypoints/openai/realtime/adapters/lingbot_world_realtime_adapter.py:102

        camera_actions = parsed.payload
        self.receive_camera_action_script(camera_actions, event_id=event_id)
        return f"kind=camera_actions, mode=script, frames={len(camera_actions)}"

    def receive_camera_control_event_payload(
        self,
        payload: Any,
        *,
        event_id: int | None,
    ) -> str:
        parsed = self.parse_camera_control_event_payload(payload, event_id=event_id)
        return self.receive_parsed_camera_control_event_payload(
            parsed, event_id=event_id
        )

    def sample_prompt(self) -> str:
        prompt = self.prompt_queue.pop_latest("prompt")
        if not isinstance(prompt, str):
            raise ValueError("prompt event payload must be a string")
        self.latest_sampled_event_id = self.prompt_queue.last_sampled_seq_id("prompt")
        return prompt

    def has_prompt(self) -> bool:
        return self.prompt_queue.has_events("prompt")


class LingBotWorldRealtimeAdapter(BaseRealtimeModelAdapter):
    def create_state(self) -> LingBotWorldRealtimeState:
        return LingBotWorldRealtimeState()

    def _state(self, session: GenerateSession) -> LingBotWorldRealtimeState:
        state = session.adapter_state
        if not isinstance(state, LingBotWorldRealtimeState):
            raise TypeError("LingBot realtime adapter state is not initialized")
        return state

    async def on_init(

View on GitHub (pinned to 0132848349)

Solutions

  1. Send the prompt event payload as a plain JSON string
  2. If you need structured prompts, use composite_input with input_types=["prompt"] and a string value
  3. Check the adapter version's expected event schema before upgrading clients

Example fix

// before
ws.send(JSON.stringify({kind: "prompt", payload: {text: "hello"}}))
// after
ws.send(JSON.stringify({kind: "prompt", payload: "hello"}))
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(prompt, str): prompt = str(prompt)

Type guard

def is_valid_prompt(p: object) -> bool: return isinstance(p, str) and len(p) > 0

Try / catch

try: prompt = adapter.sample_prompt()
except ValueError as e: if 'must be a string' in str(e): skip/repair event

Prevention

When it happens

Trigger: A realtime session where a 'prompt' event (or composite input prompt field) was ingested with a non-string payload such as {"text": ...} or a number, and sampling later pops it.

Common situations: Client wrapping the prompt in an object ({"text": "..."}) instead of sending a bare string; upstream event schema mismatch between client and adapter versions.

Related errors


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