sgl-project/sglang · error · TypeError

mm_process_config must be a dict, but got {type(cfg.mm_proce

Error message

mm_process_config must be a dict, but got {type(cfg.mm_process_config)}

What it means

--mm-process-config accepts per-modality preprocessing overrides and must deserialize into a Python dict. SGLang raises TypeError when the parsed value is not a dict (e.g. a list, string, or number), typically from malformed JSON.

Source

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

            if cfg.enable_ssl_refresh:
                raise ValueError(
                    "--enable-ssl-refresh is not supported with --enable-http2. "
                    "Granian does not support SSL certificate hot-reloading. "
                    "Use Uvicorn (the default) or handle certificate rotation externally."
                )

    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(

View on GitHub (pinned to 0132848349)

Solutions

  1. Ensure the value is a JSON object: --mm-process-config '{"image": {...}}'
  2. Validate the JSON with a linter or echo it before launching
  3. If scripting, build the dict and serialize with json.dumps instead of string concatenation

Example fix

# before
--mm-process-config '["image"]'
# after
--mm-process-config '{"image": {"max_num_frames": 16}}'
Defensive patterns

Strategy: type-guard

Validate before calling

import json
cfg = json.loads(args.mm_process_config) if isinstance(args.mm_process_config, str) else args.mm_process_config
assert isinstance(cfg, dict), 'mm_process_config must be a JSON object'

Type guard

def is_mm_process_config(v) -> bool:
    import json
    if isinstance(v, str):
        try:
            v = json.loads(v)
        except json.JSONDecodeError:
            return False
    return isinstance(v, dict)

Prevention

When it happens

Trigger: Passing --mm-process-config with JSON that parses to a non-object, e.g. '[1,2]' or '"fast"' or '64'.

Common situations: Hand-written JSON on the CLI missing braces; quoting issues in shell/env files causing truncation to a scalar; config templating emitting a bare value.

Related errors


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