sgl-project/sglang · error · ValueError

runtime.response_format must be 'envelope' or 'raw'

Error message

runtime.response_format must be 'envelope' or 'raw'

What it means

The action API validates payload['runtime']['response_format'] and only accepts 'envelope' or 'raw' (case-insensitive, default 'envelope'). Any other string raises this ValueError, which surfaces as an HTTP 400 from create_action_generation.

Source

Thrown at python/sglang/multimodal_gen/runtime/entrypoints/action/api.py:70

    "prompt",
    "reference_url",
    "request_id",
    "task",
    "video_reference",
}


def _wants_msgpack(request: Request) -> bool:
    content_type = request.headers.get("content-type", "").lower()
    accept = request.headers.get("accept", "").lower()
    return "msgpack" in content_type or "msgpack" in accept


def _response_format(payload: dict) -> str:
    runtime = payload.get("runtime") or {}
    response_format = str(runtime.get("response_format", "envelope")).lower()
    if response_format not in ("envelope", "raw"):
        raise ValueError("runtime.response_format must be 'envelope' or 'raw'")
    return response_format


def _prefer_numpy_output(payload: dict) -> None:
    runtime = payload.setdefault("runtime", {})
    runtime.setdefault("output_format", "numpy")


def _parse_form_value(value: Any) -> Any:
    if not isinstance(value, str):
        return value
    if not value.strip():
        return None
    try:
        return json.loads(value)
    except Exception:
        return value

View on GitHub (pinned to 0132848349)

Solutions

  1. Set runtime.response_format to 'envelope' (default) or 'raw' exactly, lowercased
  2. Omit the field entirely to get the default 'envelope' behavior
  3. Check the endpoint's schema/docs for the accepted enum values

Example fix

// before
{"input": {...}, "runtime": {"response_format": "json"}}

// after
{"input": {...}, "runtime": {"response_format": "raw"}}
Defensive patterns

Strategy: validation

Validate before calling

def normalize_response_format(payload):
    rf = (payload.get("runtime") or {}).get("response_format", "envelope")
    rf = str(rf).strip().lower()
    assert rf in ("envelope", "raw"), f"bad response_format: {rf!r}"
    payload.setdefault("runtime", {})["response_format"] = rf
    return payload

Type guard

def is_valid_response_format(v: str) -> bool:
    return isinstance(v, str) and v.strip().lower() in ("envelope", "raw")

Prevention

When it happens

Trigger: POSTing to the action generation endpoint with body {"runtime": {"response_format": "json"}} or 'ENVELOPE ' (trailing space), or misspelling the value.

Common situations: Clients guessing the response format option names; copy-paste from a different API version; passing 'msgpack' (which is a separate flag) as response_format.

Related errors


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