sgl-project/sglang · error · TypeError

{modality.name} must be a list or None, got {type(data_list)

Error message

{modality.name} must be a list or None, got {type(data_list)}

What it means

validate_mm_data -> _validate_one_modality enforces that per-modality fields of the mm_data dict (images, audios, videos) are either None or a Python list. Passing a single bare item, tuple, numpy array, or generator raises this TypeError.

Source

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

        for modality, iterator in data_iterators.items():
            try:
                next(iterator)
                logger.warning(
                    f"Warning: More {modality.name.lower()} data items provided than corresponding tokens found in the prompt."
                )
            except StopIteration:
                pass
            except Exception:
                pass

        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(

View on GitHub (pinned to 0132848349)

Solutions

  1. Wrap single items in a list: {'images': [img]}
  2. Convert tuples/arrays: list(items)
  3. Leave the field as None when the modality is absent

Example fix

// before
mm_data = {'images': pil_img, 'audios': (a1, a2)}
// after
mm_data = {'images': [pil_img], 'audios': [a1, a2]}
Defensive patterns

Strategy: type-guard

Type guard

def valid_mm_field(v):
    return v is None or (isinstance(v, list) and all(not isinstance(x, (tuple, set)) for x in v))

Prevention

When it happens

Trigger: Calling the processor with mm_data={'images': single_pil_image} or {'audios': (a1, a2)} (tuple) or a numpy array instead of a list.

Common situations: Single-image convenience expectations carried over from other APIs; JSON-decoded tuples; forgetting to wrap the result of a generator/filter in list().

Understand the failure class

Background: "Wrong argument type", "must be a string", "expected Array or Prism::Scope": TypeError and ArgumentError when a library receives a value of the wrong type — this error's family across 28 libraries.

Related errors


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