sgl-project/sglang · error · ValueError

Component attention backend key must be a string

Error message

Component attention backend key must be a string

What it means

After parsing, each key of the component-attention-backend map must be a Python str. This only fires for programmatic dict input (or JSON) whose keys are non-strings (e.g. ints from a YAML config where 42 was used as a component key), since CLI string parsing always yields str keys.

Source

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

            if not pair:
                continue
            if "=" not in pair:
                raise ValueError(
                    "component_attention_backends must use component=backend entries"
                )
            component, backend = pair.split("=", 1)
            result[component.strip()] = backend.strip()
        return result

    @classmethod
    def _normalize_component_attention_backends(
        cls, value: dict[str, str] | str | None
    ) -> dict[str, str]:
        raw = cls._parse_component_attention_backend_map(value)
        normalized: dict[str, str] = {}
        for component, backend in raw.items():
            if not isinstance(component, str):
                raise ValueError("Component attention backend key must be a string")
            component_name = component.strip().replace("-", "_")
            if not component_name:
                raise ValueError("Component attention backend key must not be empty")
            normalized[component_name] = cls._normalize_attention_backend_name(backend)
        return normalized

    def resolve_component_attention_backend(
        self, *component_names: str | None
    ) -> tuple[AttentionBackendEnum | None, str | None]:
        for component_name in component_names:
            if component_name is None:
                continue
            key = component_name.replace("-", "_")
            fallback_keys = [key]
            if key.endswith("_2"):
                # Secondary two-stage components inherit the base component
                # backend unless explicitly overridden.
                fallback_keys.append(key[:-2])

View on GitHub (pinned to 0132848349)

Solutions

  1. Convert keys to strings: {str(k): v for k, v in cfg.items()}
  2. Quote keys in the JSON/YAML source
  3. Fix the config loader to preserve string keys

Example fix

# before
backends = {int(k): v for k, v in cfg.items()}
# after
backends = {str(k): v for k, v in cfg.items()}
Defensive patterns

Strategy: type-guard

Validate before calling

backends = {str(k): v for k, v in raw_backends.items()}

Type guard

def has_str_keys(d: dict) -> bool:
    return all(isinstance(k, str) and k.strip() for k in d)

Prevention

When it happens

Trigger: ServerArgs(component_attention_backends={42: 'flash'}) or JSON '{"42": ...}' parsed to non-str keys via a permissive loader.

Common situations: Loading config from YAML/JSON where numeric-looking keys were auto-converted; constructing the dict from another mapping with non-str keys.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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