sgl-project/sglang · error · TypeError

mm_process_config['{key}'] must be a dict, but got {type(cfg

Error message

mm_process_config['{key}'] must be a dict, but got {type(cfg.mm_process_config[key])}

What it means

Within --mm-process-config, only the keys image, video, and audio are inspected, and each must map to a dict of override fields. This TypeError is raised when one of those keys maps to a non-dict value (string, number, list).

Source

Thrown at python/sglang/srt/server_args.py:4388

    def _handle_multimodal(self):
        """Validate mm_process_config structure before model loading."""
        cfg = resolving_view(self)
        if (
            cfg.mm_preprocess_cache_size_mb is not None
            and cfg.mm_preprocess_cache_size_mb < 0
        ):
            raise ValueError("mm_preprocess_cache_size_mb must be non-negative")
        if cfg.mm_process_config is not None:
            if not isinstance(cfg.mm_process_config, dict):
                raise TypeError(
                    f"mm_process_config must be a dict, "
                    f"but got {type(cfg.mm_process_config)}"
                )
            for key in ("image", "video", "audio"):
                if key in cfg.mm_process_config and not isinstance(
                    cfg.mm_process_config[key], dict
                ):
                    raise TypeError(
                        f"mm_process_config['{key}'] must be a dict, "
                        f"but got {type(cfg.mm_process_config[key])}"
                    )

    def _handle_media_url_security(self):
        """Normalize and publish the media URL policy before workers start."""
        cfg = resolving_view(self)
        self._declare(
            "_handle_media_url_security",
            allowed_media_domains=configure_media_url_security(
                cfg.allowed_media_domains,
                cfg.media_url_max_file_size_mb,
            ),
        )

    def _handle_deprecated_args(self):
        cfg = resolving_view(self)
        if cfg.disable_fast_image_processor:

View on GitHub (pinned to 0132848349)

Solutions

  1. Wrap per-modality settings in an object: {"image": {"...": ...}}
  2. Check the model's mm preprocessing docs for accepted keys per modality
  3. Echo the final arg string and run it through python -c 'import json,sys; json.load(open(...))' or json.loads to verify structure

Example fix

# before
--mm-process-config '{"image": 4}'
# after
--mm-process-config '{"image": {"num_threads": 4}}'
Defensive patterns

Strategy: type-guard

Validate before calling

import json
cfg = json.loads(args.mm_process_config)
for k in ('image', 'video', 'audio'):
    if k in cfg:
        assert isinstance(cfg[k], dict), f'{k} settings must be an object'

Type guard

def valid_mm_sections(cfg: dict) -> bool:
    return all(
        isinstance(cfg.get(k), dict) for k in ('image', 'video', 'audio') if k in cfg
    )

Prevention

When it happens

Trigger: Passing --mm-process-config '{"image": "fast"}' or '{"video": [1,2]}' — a valid top-level dict but a non-dict value under image/video/audio.

Common situations: Shorthand attempts like {"image": 4} meaning 'use 4 threads'; nested JSON quoting broken by the shell; schema drift from older config formats.

Related errors


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