{"record":{"id":"8ea189b820dde599","repo":"sgl-project/sglang","slug":"peft-adapter-config-json-must-contain-a-json-objec","errorCode":null,"errorMessage":"PEFT adapter_config.json must contain a JSON object","messagePattern":"PEFT adapter_config\\.json must contain a JSON object","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/pipelines_core/lora/peft_adapter.py","lineNumber":83,"sourceCode":"                f\"safetensors metadata {key!r} must be a positive integer\"\n            ) from error\n        if not math.isfinite(numeric) or numeric <= 0 or not numeric.is_integer():\n            raise ValueError(f\"safetensors metadata {key!r} must be a positive integer\")\n        declared.append((key, int(numeric)))\n    values = {value for _, value in declared}\n    if len(values) > 1:\n        raise ValueError(f\"conflicting safetensors LoRA alpha metadata: {declared}\")\n    return declared[0][1] if declared else None\n\n\ndef load_peft_config(weight_path: str) -> dict[str, Any]:\n    path = Path(weight_path).with_name(\"adapter_config.json\")\n    config = {}\n    if path.is_file():\n        with path.open(encoding=\"utf-8\") as file:\n            config = json.load(file)\n    if not isinstance(config, dict):\n        raise ValueError(\"PEFT adapter_config.json must contain a JSON object\")\n    metadata_alpha = _load_safetensors_lora_alpha(weight_path)\n    config_alpha = get_peft_lora_alpha(config)\n    if (\n        metadata_alpha is not None\n        and config_alpha is not None\n        and metadata_alpha != config_alpha\n    ):\n        raise ValueError(\n            \"adapter_config.json lora_alpha conflicts with safetensors metadata: \"\n            f\"{config_alpha} != {metadata_alpha}\"\n        )\n    if metadata_alpha is not None:\n        config.setdefault(\"lora_alpha\", metadata_alpha)\n    return config\n\n\ndef get_peft_lora_alpha(config: Mapping[str, Any]) -> int | None:\n    alpha = config.get(\"lora_alpha\")","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/pipelines_core/lora/peft_adapter.py#L65-L101","documentation":"load_peft_config reads adapter_config.json next to the weights and requires it to be a JSON object (dict). If the file exists but parses to a list, string, number, null, or an empty non-dict value, this ValueError is raised. Note json.load of a totally malformed file would raise JSONDecodeError instead; this specifically covers valid JSON of the wrong shape.","triggerScenarios":"Placing an adapter_config.json that contains a JSON array or scalar string next to the LoRA weights, then calling load_lora_adapter / load_peft_config on that path.","commonSituations":"Hand-written config files, config generators that emit wrapped arrays, or accidentally pointing weight_path at a directory containing an unrelated adapter_config.json.","solutions":["Validate adapter_config.json parses to an object: python -c \"import json;print(type(json.load(open('adapter_config.json'))))\"","Fix the file to be a flat JSON object of PEFT config keys (peft_type, lora_alpha, r, target_modules, ...)","Ensure weight_path points at the actual adapter directory"],"exampleFix":"// before: adapter_config.json contains [ {\"lora_alpha\": 16} ]\n// after:  adapter_config.json contains { \"lora_alpha\": 16, \"peft_type\": \"LORA\", \"r\": 16 }","handlingStrategy":"validation","validationCode":"import json\ncfg = json.load(open(p / \"adapter_config.json\"))\nassert isinstance(cfg, dict), \"adapter_config.json must be a JSON object\"","typeGuard":"def is_peft_config_object(cfg) -> bool:\n    return isinstance(cfg, dict)","tryCatchPattern":"try:\n    cfg = load_peft_config(path)\nexcept ValueError as e:\n    if \"must contain a JSON object\" in str(e):\n        cfg = json.load(open(path / \"adapter_config.json\"))\n        if not isinstance(cfg, dict):\n            raise  # genuinely malformed, fix the file\n    raise","preventionTips":["Generate adapter_config.json with json.dump of a dict, never hand-wrap in arrays","Point loaders at the adapter directory produced by PEFT export"],"tags":["lora","peft","json","config"],"backgroundTag":"invalid-config-file","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}