sgl-project/sglang · error · ValueError
Invalid modality: {modality}
Error message
Invalid modality: {modality} What it means
Raised by MMReceiver._set_part_grid when the modality passed in is not a key in _MODALITY_GRID_ATTRS (which only maps IMAGE, VIDEO, AUDIO to their grid attribute names). It guards against writing grid data into an attribute that does not exist for the part being assembled.
Source
Thrown at python/sglang/srt/disaggregation/encoder/receiver.py:590
self._set_video_meta_for_part(part_idx, kwargs)
if modality == Modality.IMAGE:
self._set_image_meta_for_part(part_idx, kwargs)
def _set_image_meta_for_part(self, part_idx, source):
for attr_name in _GENERAL_IMAGE_META_ATTRS:
val = (
source.get(attr_name)
if isinstance(source, dict)
else getattr(source, attr_name, None)
)
if val is not None:
getattr(self, attr_name)[part_idx] = val
def _set_part_grid(self, part_idx, modality, grid):
"""Set the grid for one part according to modality (IMAGE/VIDEO/AUDIO)."""
spec = _MODALITY_GRID_ATTRS.get(modality)
if spec is None:
raise ValueError(f"Invalid modality: {modality}")
attr_name, flatten = spec
value = grid.flatten() if flatten else grid
getattr(self, attr_name)[part_idx] = value
def _set_video_meta_for_part(self, part_idx, source):
"""Copy video_timestamps and second_per_grid_ts from source (dict or object)."""
for attr_name in self.video_meta_attrs:
val = (
source.get(attr_name)
if isinstance(source, dict)
else getattr(source, attr_name, None)
)
if val is not None:
getattr(self, attr_name)[part_idx] = val
@classmethod
def from_embedding_data(
cls,View on GitHub (pinned to 0132848349)
Solutions
- Coerce the value to the Modality enum before calling (e.g. Modality(modality) or a mapping table for legacy string values).
- If adding a new modality, add its (attr_name, flatten) entry to _MODALITY_GRID_ATTRS.
- Log/inspect the incoming modality value to find where a raw string or None slips through.
Example fix
# before receiver._set_part_grid(idx, part.modality, grid) # part.modality is "image" # after receiver._set_part_grid(idx, Modality(part.modality.upper()), grid)
Defensive patterns
Strategy: validation
Validate before calling
from sglang.srt.disaggregation.encoder.receiver import _MODALITY_GRID_ATTRS
def is_supported_modality(modality) -> bool:
return modality in _MODALITY_GRID_ATTRS
assert is_supported_modality(part.modality), f"unsupported modality: {part.modality!r}" Type guard
def is_valid_modality(m) -> bool:
from sglang.srt.multimodal import Modality # adjust import as needed
return isinstance(m, Modality) and m in (Modality.IMAGE, Modality.VIDEO, Modality.AUDIO) Try / catch
try:
receiver._set_part_grid(idx, modality, grid)
except ValueError:
logger.warning("dropping part with unknown modality %r", modality) Prevention
- Normalize deserialized modality strings through the Modality enum immediately after decode.
- When adding a modality, update _MODALITY_GRID_ATTRS in the same change.
- Reject unknown modality values at the transport boundary with a clear 400-style error.
When it happens
Trigger: Calling the receiver's part-grid setter (from __init__ or add) with a modality value that is not Modality.IMAGE/VIDEO/AUDIO — e.g. a raw string like "image" vs the enum, None, or a newly added modality that lacks a mapping in _MODALITY_GRID_ATTRS.
Common situations: Deserializing grid metadata where modality arrived as a lowercase string instead of the Modality enum; extending the modality set without updating _MODALITY_GRID_ATTRS; corrupted/malformed payloads from an older encoder version.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- mm_content_hashes has {len(image_hashes)} entries for {image
- gRPC encode only supports IMAGE modality, got: {non_image}
- Invalid modality string: {modality_str}. Valid modalities ar
- Unsupported modality for EPD preprocessing: {modality}
- cos/sin shape does not cover image tokens and head_dim
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/236abf349ec52242.
Report an issue: GitHub.