{"record":{"id":"f5cf1f5d8470c45c","repo":"sgl-project/sglang","slug":"source-must-be-a-mapping-or-expose-to-dict-go","errorCode":null,"errorMessage":"{source} must be a mapping or expose to_dict(), got {type(value).__name__}","messagePattern":"(.+?) must be a mapping or expose to_dict\\(\\), got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/model_loader/checkpoint_quantization.py","lineNumber":55,"sourceCode":"\n\ndef _get_field(config: object, name: str) -> Any:\n    if isinstance(config, Mapping):\n        return config.get(name)\n    return getattr(config, name, None)\n\n\ndef _to_metadata_dict(value: object, source: QuantMetadataSource) -> dict[str, Any]:\n    if isinstance(value, Mapping):\n        return deepcopy(dict(value))\n\n    to_dict = getattr(value, \"to_dict\", None)\n    if callable(to_dict):\n        metadata = to_dict()\n        if isinstance(metadata, Mapping):\n            return deepcopy(dict(metadata))\n\n    raise TypeError(\n        f\"{source} must be a mapping or expose to_dict(), \"\n        f\"got {type(value).__name__}\"\n    )\n\n\ndef _select_hf_quant_metadata(\n    hf_config: object,\n) -> tuple[QuantMetadataSource, object] | None:\n    value = _get_field(hf_config, \"quantization_config\")\n    if value is not None:\n        return \"quantization_config\", value\n\n    text_config = _get_field(hf_config, \"text_config\")\n    value = _get_field(text_config, \"quantization_config\")\n    if value is not None:\n        return \"text_config.quantization_config\", value\n\n    value = _get_field(hf_config, \"compression_config\")","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/model_loader/checkpoint_quantization.py#L37-L73","documentation":"_to_metadata_dict accepts either a Mapping or an object with a callable to_dict() that returns a Mapping, and raises TypeError otherwise when normalizing quantization metadata. It is used by resolve_checkpoint_quant_spec to read HF quantization_config style metadata. The error means the value passed as quant metadata is of an unexpected type (e.g. a string, list, or object whose to_dict returns non-mapping).","triggerScenarios":"Calling resolve_checkpoint_quant_spec with quant_config that is neither a dict/Mapping nor exposes to_dict() returning a Mapping; e.g. passing hf_quant_config.quantization_config as a raw JSON string or a list, or a dataclass whose to_dict returns None.","commonSituations":"Custom or non-standard HuggingFace quantization_config formats, checkpoints with quant config stored as a string, or caller code passing model_config attributes directly without dict conversion.","solutions":["Pass a plain dict (or Mapping) as the quant metadata value","If using a config object, ensure it exposes to_dict() returning a dict","Normalize earlier: json.loads / dict(...) before calling resolve_checkpoint_quant_spec","Inspect type(value) in the error message to find which field is malformed and fix its producer"],"exampleFix":"// before\nspec = resolve_checkpoint_quant_spec(quant_config=model_config.hf_config.quantization_config_string)\n// after\nimport json\nspec = resolve_checkpoint_quant_spec(quant_config=json.loads(model_config.hf_config.quantization_config_string))","handlingStrategy":"type-guard","validationCode":"from collections.abc import Mapping\n\ndef as_quant_metadata(value, source='quant_config'):\n    if isinstance(value, Mapping):\n        return dict(value)\n    to_dict = getattr(value, 'to_dict', None)\n    if callable(to_dict):\n        out = to_dict()\n        if isinstance(out, Mapping):\n            return dict(out)\n    raise TypeError(f'{source} must be a mapping or expose to_dict(), got {type(value).__name__}')","typeGuard":"def is_quant_metadata(value) -> bool:\n    if isinstance(value, Mapping):\n        return True\n    to_dict = getattr(value, 'to_dict', None)\n    return callable(to_dict) and isinstance(to_dict(), Mapping)","tryCatchPattern":null,"preventionTips":["Always pass plain dicts for quant metadata","Validate config shape right after parsing checkpoint config.json","Add unit tests covering string/list quant_config inputs"],"tags":["quantization","type-validation","checkpoint","metadata"],"backgroundTag":"config-type-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}