{"record":{"id":"52a01c350e4fd693","repo":"sgl-project/sglang","slug":"component-attention-backends-must-be-a-dict-or-a-c","errorCode":null,"errorMessage":"component_attention_backends must be a dict or a comma-separated component=backend string","messagePattern":"component_attention_backends must be a dict or a comma-separated component=backend string","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/server_args/server_args.py","lineNumber":1102,"sourceCode":"            )\n        )\n        if policy not in RESIDENCY_POLICIES:\n            raise ValueError(\n                f\"unknown residency policy {policy!r} for component \"\n                f\"{component_name!r}, expected one of {RESIDENCY_POLICIES}\"\n            )\n        return prefetch, resident, policy\n\n    @staticmethod\n    def _parse_component_attention_backend_map(\n        value: dict[str, str] | str | None,\n    ) -> dict[str, str]:\n        if value is None or value == \"\":\n            return {}\n        if isinstance(value, dict):\n            return dict(value)\n        if not isinstance(value, str):\n            raise ValueError(\n                \"component_attention_backends must be a dict or a comma-separated component=backend string\"\n            )\n\n        try:\n            parsed = json.loads(value)\n            if not isinstance(parsed, dict):\n                raise ValueError\n            return parsed\n        except (json.JSONDecodeError, ValueError):\n            pass\n\n        result: dict[str, str] = {}\n        for pair in value.split(\",\"):\n            pair = pair.strip()\n            if not pair:\n                continue\n            if \"=\" not in pair:\n                raise ValueError(","sourceCodeStart":1084,"sourceCodeEnd":1120,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/server_args/server_args.py#L1084-L1120","documentation":"--component-attention-backends accepts either a dict (programmatic use) or a string that is JSON or comma-separated component=backend pairs. Passing any other type (int, list, tuple, None-adjacent objects) raises this error before parsing is attempted.","triggerScenarios":"Calling from_cli_args or _normalize_component_attention_backends with component_attention_backends=[\"dit=flash\"] or 3 instead of a dict/str; passing a list of pair-strings programmatically.","commonSituations":"Programmatic ServerArgs construction where a YAML/JSON config was loaded with a wrong type; passing a list because the CLI appears repeatable; None handling delegated incorrectly.","solutions":["Pass a dict {'dit': 'flash'} directly","Or pass a string: 'dit=flash' or '{\"dit\": \"flash\"}'","Fix the upstream config loader so the field is str or dict"],"exampleFix":"# before\nargs = ServerArgs(component_attention_backends=[\"dit=flash\"])\n# after\nargs = ServerArgs(component_attention_backends={\"dit\": \"flash\"})","handlingStrategy":"type-guard","validationCode":"if not isinstance(backends, (str, dict)) or backends in (None, ''):\n    raise TypeError('component_attention_backends must be str or dict')","typeGuard":"def is_backend_map_input(v) -> bool:\n    return v is None or v == '' or isinstance(v, (str, dict))","tryCatchPattern":null,"preventionTips":["Type config fields as str|dict|None","Validate config types before ServerArgs construction"],"tags":["config","type-error","attention-backend"],"backgroundTag":"invalid-argument-type","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}