sgl-project/sglang · error · ValueError

For {modality}, when providing a 'processor_output' or 'prec

Error message

For {modality}, when providing a 'processor_output' or 'precomputed_embedding', you must pass exactly one item; received {len(data_list)} items (formatted at indices {formatted_indices}).

What it means

When a modality list contains a 'preprocessed' item (processor_output or precomputed_embedding), _validate_one_modality requires that list to have exactly one element. Mixing precomputed embeddings with additional raw items is ambiguous and rejected.

Source

Thrown at python/sglang/srt/multimodal/processors/base_processor.py:1055

        return futures, task_info

    @staticmethod
    def _validate_one_modality(modality: Modality, data_list: Optional[list]):
        if data_list is None:
            return
        if not isinstance(data_list, list):
            raise TypeError(
                f"{modality.name} must be a list or None, got {type(data_list)}"
            )

        formatted_indices = []
        for idx, item in enumerate(data_list):
            if BaseMultimodalProcessor._is_preprocessed_input(item):
                formatted_indices.append(idx)

        if formatted_indices:
            if len(data_list) != 1:
                raise ValueError(
                    f"For {modality}, when providing a 'processor_output' or "
                    f"'precomputed_embedding', you must pass exactly one item; "
                    f"received {len(data_list)} items (formatted at indices {formatted_indices})."
                )

    @staticmethod
    def validate_mm_data(
        image_data: Optional[list] = None,
        video_data: Optional[list] = None,
        audio_data: Optional[list] = None,
    ):
        """
        Validate multimodal input lists per modality.

        Rule per modality (image/video/audio):
        - Either the list has exactly one item and that single item is a dict with
          format in {"processor_output", "precomputed_embedding"};
        - Or, the list contains only "normal" items (i.e., does not include any

View on GitHub (pinned to 0132848349)

Solutions

  1. Split the request: send the precomputed item alone, and raw images in a separate request
  2. If all items are precomputed of the same shape, check the current API for a batched precomputed format; otherwise send sequentially
  3. Drop the precomputed item and send raw media so the processor recomputes everything consistently

Example fix

// before
mm_data = {'images': [{'precomputed_embedding': emb}, pil_img]}
// after
r1 = processor.process_mm_data_async({'images': [{'precomputed_embedding': emb}]}, ...)
r2 = processor.process_mm_data_async({'images': [pil_img]}, ...)
Defensive patterns

Strategy: validation

Validate before calling

for mod, lst in mm_data.items():
    if lst and any('precomputed_embedding' in it or 'processor_output' in it for it in lst if isinstance(it, dict)):
        assert len(lst) == 1, 'precomputed items must be sent one per request'

Type guard

def is_precomputed(item):
    return isinstance(item, dict) and ('precomputed_embedding' in item or 'processor_output' in item)

Prevention

When it happens

Trigger: Passing something like {'images': [precomputed_item, raw_pil_image]} — i.e. a precomputed embedding alongside other images in the same modality list.

Common situations: Caching embeddings per prompt then appending a new raw image; migrating from single-image to multi-image prompts while keeping the precomputed path; batch payloads reusing one embedding for several slots.

Related errors


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