sgl-project/sglang · error · ValueError

{option} must be a dict or a comma-separated component=value

Error message

{option} must be a dict or a comma-separated component=value string

What it means

_parse_component_value_map accepts None, '', a dict, or a comma-separated 'component=value' string (also JSON object strings). Any other type (int, list, bool) raises this error; option names the offending setting.

Source

Thrown at python/sglang/multimodal_gen/runtime/server_args/server_args.py:1038

        try:
            return AttentionBackendEnum[normalized.upper()].name.lower()
        except KeyError:
            raise ValueError(
                f"Invalid attention backend '{backend}'. "
                f"Available options are: {[e.name.lower() for e in AttentionBackendEnum]}"
            ) from None

    @staticmethod
    def _parse_component_value_map(
        value: dict[str, Any] | str | None, *, option: str
    ) -> dict[str, str]:
        """Parse a ``component=value`` map, the same shape as component backends."""
        if value is None or value == "":
            return {}
        if isinstance(value, dict):
            return {str(k): str(v) for k, v in value.items()}
        if not isinstance(value, str):
            raise ValueError(
                f"{option} must be a dict or a comma-separated component=value string"
            )
        try:
            parsed = json.loads(value)
            if isinstance(parsed, dict):
                return {str(k): str(v) for k, v in parsed.items()}
        except json.JSONDecodeError:
            pass
        result: dict[str, str] = {}
        for pair in value.split(","):
            pair = pair.strip()
            if not pair:
                continue
            if "=" not in pair:
                raise ValueError(f"{option} must use component=value entries")
            component, entry = pair.split("=", 1)
            result[component.strip()] = entry.strip()
        return result

View on GitHub (pinned to 0132848349)

Solutions

  1. Join list values: ','.join(parts) or pass a dict {'text': '8'}
  2. Pass a JSON object string like '{"text": "8"}' if you need JSON
  3. Ensure the config field is typed as str or dict, not list

Example fix

# before
args.layerwise_tuning_for = ["text=8", "vision=16"]
# after
args.layerwise_tuning_for = "text=8,vision=16"
Defensive patterns

Strategy: type-guard

Validate before calling

if isinstance(value, (list, tuple)):
    value = ','.join(value)
if not isinstance(value, (str, dict)) and value not in (None, ''):
    raise SystemExit('component map must be a dict or comma-separated string')

Type guard

def is_component_map(v) -> bool:
    return v is None or v == '' or isinstance(v, (str, dict))

Prevention

When it happens

Trigger: Passing a list like ['text=8', 'vision=16'] or an int to a component-map option; JSON that parses to a non-dict (e.g. a JSON array string) falls through to the type check on the next iteration path.

Common situations: Building component maps programmatically and passing sequences instead of joined strings; config schemas that type the field as a list; JSON strings that contain arrays instead of objects.

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/cee61cb61a87f6fb. Report an issue: GitHub.