sgl-project/sglang · error · ValueError
Pi05 v1 expects one prompt per action request
Error message
Pi05 v1 expects one prompt per action request
What it means
The Pi05 v1 preprocessing stage requires exactly one text prompt per action request. The stage reads raw_observation['prompt'], stringifies it (or each element if it's a list), and rejects anything that does not reduce to a single prompt, because the downstream model invocation is built for batch size 1.
Source
Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/pi05_preprocess.py:155
encoded = self.tokenizer(
full_prompts,
max_length=self.config.max_token_len,
padding="max_length",
truncation=True,
return_tensors="pt",
)
return encoded["input_ids"].to(torch.long), encoded["attention_mask"].to(
torch.bool
)
def __call__(self, raw_observation: dict[str, Any]) -> VLAObservationBatch:
prompt_value = raw_observation.get("prompt", "")
if isinstance(prompt_value, list):
prompt = [str(x) for x in prompt_value]
else:
prompt = [str(prompt_value)]
if len(prompt) != 1:
raise ValueError("Pi05 v1 expects one prompt per action request")
raw_images = raw_observation.get("images") or {}
image_masks_in = raw_observation.get("image_masks") or {}
camera_order = tuple(
raw_observation.get("camera_order") or self.config.image_keys
)
images: dict[str, torch.Tensor] = {}
image_masks: dict[str, torch.Tensor] = {}
for key in camera_order:
value = raw_images.get(key)
is_present = value is not None and bool(image_masks_in.get(key, True))
if is_present:
tensor = _preprocess_image(value, self.config.image_size)
else:
channels = 3
height, width = self.config.image_size
tensor = torch.ones(channels, height, width, dtype=torch.float32) * -1.0View on GitHub (pinned to 0132848349)
Solutions
- Set raw_observation['prompt'] to a single string (or a one-element list) per request.
- If you need multiple prompts, split them into separate action requests and call the stage once each.
- Add a pre-check in your data loader that asserts len(prompt)==1 before dispatching.
Example fix
# before
raw_observation = {"prompt": ["pick up the cup", "stack the block"]}
stage(raw_observation)
# after
for p in ["pick up the cup", "stack the block"]:
stage({"prompt": p}) Defensive patterns
Strategy: validation
Validate before calling
p = raw_observation.get("prompt", "")
plist = p if isinstance(p, list) else [p]
assert len(plist) == 1, f"expected 1 prompt, got {len(plist)}" Type guard
from typing import Union
def is_single_prompt(obs: dict) -> bool:
p = obs.get("prompt", "")
return not isinstance(p, list) or len(p) == 1 Try / catch
try:
out = stage(raw_observation)
except ValueError as e:
if "one prompt per action request" in str(e):
# split and retry per-prompt
...
raise Prevention
- Keep one observation dict per environment step.
- Unit-test your data adapter with a two-prompt list to confirm it splits.
When it happens
Trigger: Calling the pi05 preprocess stage with raw_observation['prompt'] being a list of length != 1, e.g. ['a','b'], or a value that stringifies to something combined with a list of 2+ items. Any multi-prompt batched request triggers it.
Common situations: Porting batched VLA inference code from another framework that supports multiple prompts per request; accidentally wrapping the prompt in extra list nesting; feeding a list of prompts when iterating a dataset without splitting per-sample.
Related errors
- Pi05 v1 expects one state vector per request
- Pi05Pipeline v1 supports same-process execution only. Use pr
- VLA action expert should not share the prefix TP layout. Use
- Pi05 state dim must be <= {self.config.state_dim}, got {stat
- Pi05 noise must have shape {expected}, got {tuple(noise_tens
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/372ffe62b1f0163e.
Report an issue: GitHub.