sgl-project/sglang · error · ValueError
Feature attrs ({_mm_feature_attrs[modality]}) not found in {
Error message
Feature attrs ({_mm_feature_attrs[modality]}) not found in {mm_inputs} What it means
_get_mm_feature looks up the expected feature tensor for a modality by trying each attribute name in _mm_feature_attrs[modality] (e.g. 'image_embeddings', 'audio_features' variants); if none of them is a key in mm_inputs, it raises ValueError because it cannot find the multimodal feature payload.
Source
Thrown at python/sglang/srt/disaggregation/encoder/server.py:398
async with rid_lock:
rid_to_receive_endpoint.pop(state.req_id, None)
rid_to_receive_count.pop(state.req_id, None)
async with cond_dict_lock:
rid_to_cond.pop(state.req_id, None)
_mm_feature_attrs = {
Modality.IMAGE: ["pixel_values"],
Modality.VIDEO: ["pixel_values_videos"],
Modality.AUDIO: ["input_features"],
}
def _get_mm_feature(mm_inputs, modality):
for attr in _mm_feature_attrs[modality]:
if attr in mm_inputs:
return mm_inputs[attr]
raise ValueError(
f"Feature attrs ({_mm_feature_attrs[modality]}) not found in {mm_inputs}"
)
def _normalize_aux_value(val):
"""Normalize aux values to pickle types compatible with safe_pickle_loads.
HF multimodal processors (e.g. Qwen3-VL/Omni) emit numpy arrays for
fields like ``video_timestamps`` / ``second_per_grid_ts``. ``numpy.*`` is
not in SafeUnpickler's allowlist, so the receiver would refuse to load
those payloads. Convert numpy values to torch tensors (numeric) or plain
Python lists (object dtype) before pickling.
"""
if val is None:
return None
if isinstance(val, np.ndarray):
if val.dtype == object:
return val.tolist()View on GitHub (pinned to 0132848349)
Solutions
- Log/inspect the actual keys of mm_inputs and compare with _mm_feature_attrs[modality]
- Fix the preprocessor output to emit the expected attribute name for that modality
- If integrating a new model, add its feature attribute name to _mm_feature_attrs
- Ensure the modality string in the request matches the payload type
Example fix
# before
mm_inputs = {"img_embeds": ...} # not a recognized key
# after
mm_inputs = {"image_embeddings": ...} # recognized by _mm_feature_attrs Defensive patterns
Strategy: type-guard
Validate before calling
known = set().union(*_mm_feature_attrs.values())
if not (set(mm_inputs) & known):
raise ValueError(f'mm_inputs lacks any known feature key: {sorted(mm_inputs)}') Type guard
def has_mm_feature(mm_inputs: dict, modality: str) -> bool:
return any(a in mm_inputs for a in _mm_feature_attrs[modality]) Prevention
- Pin preprocessor version to the encoder release
- Add new model feature keys to _mm_feature_attrs during integration
- Round-trip test preprocess output against the lookup
When it happens
Trigger: Calling _prepare_encode_context (or the encode context builder) with an mm_inputs dict missing the modality's feature key — e.g. preprocessor output schema changed, wrong modality tag, or the features were nested/renamed in a new model integration.
Common situations: Upgrading the preprocessor or model code so feature keys are renamed; passing a request for modality 'image' that actually contains audio keys; a new multimodal model whose processor emits a different field name not yet added to _mm_feature_attrs.
Related errors
- {path}.kind must be a non-empty string
- Grid dim ({_mm_grid_attrs[modality]}) not found in {mm_input
- Z-Image text embeddings must have shape [seq, dim] or [batch
- f"Unsupported patch_size type: {type(patch_size)}"
- f"Expected camera embedding shape [B, C, F, H, W], got {tupl
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/71eca69357b3c3cc.
Report an issue: GitHub.