{"record":{"id":"f65c7a9d443a70cc","repo":"sgl-project/sglang","slug":"batching-config-rule-requires-model-or-model-conta","errorCode":null,"errorMessage":"batching config rule requires model or model_contains","messagePattern":"batching config rule requires model or model_contains","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/managers/dynamic_batch_admission.py","lineNumber":111,"sourceCode":"            model_contains=_optional_str(data.get(\"model_contains\")),\n            resolution=_optional_str(data.get(\"resolution\")),\n            device_memory_gb_min=_optional_float(data.get(\"device_memory_gb_min\")),\n            device_memory_gb_max=_optional_float(data.get(\"device_memory_gb_max\")),\n            offload=_optional_bool(data.get(\"offload\")),\n            max_batch_size=int(data[\"max_batch_size\"]),\n            max_cost=_optional_float(data.get(\"max_cost\")),\n            source=source,\n        )\n        rule.validate()\n        return rule\n\n    def validate(self) -> None:\n        if self.model is not None and self.model_contains is not None:\n            raise ValueError(\n                \"batching config rule cannot set both model and model_contains\"\n            )\n        if self.model is None and self.model_contains is None:\n            raise ValueError(\"batching config rule requires model or model_contains\")\n        if self.max_batch_size < 1:\n            raise ValueError(\"batching config rule max_batch_size must be >= 1\")\n        if self.max_cost is not None and self.max_cost <= 0.0:\n            raise ValueError(\"batching config rule max_cost must be > 0\")\n        if (\n            self.device_memory_gb_min is not None\n            and self.device_memory_gb_max is not None\n            and self.device_memory_gb_min > self.device_memory_gb_max\n        ):\n            raise ValueError(\n                \"batching config rule device_memory_gb_min must be <= device_memory_gb_max\"\n            )\n\n    def matches(\n        self,\n        *,\n        model_path: str,\n        resolution: str | None,","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/managers/dynamic_batch_admission.py#L93-L129","documentation":"Every BatchingRule needs at least one component selector: either model (exact match) or model_contains (substring match). Without one the rule could not be attributed to any model, so validate() rejects it.","triggerScenarios":"A rule dict that has max_batch_size but neither \"model\" nor \"model_contains\" keys (both parse to None), e.g. {\"resolution\": \"512\", \"max_batch_size\": 2}.","commonSituations":"Author intended a resolution-only or device-memory-only rule and assumed a default/catch-all selector exists; or trimmed a rule down during editing and removed the selector.","solutions":["Add \"model\": \"<exact name>\" or \"model_contains\": \"<substring>\" to the rule","Use model_contains with a broad substring only if a catch-all was intended"],"exampleFix":"// before\n{\"resolution\": \"512\", \"max_batch_size\": 2}\n// after\n{\"model_contains\": \"\", \"resolution\": \"512\", \"max_batch_size\": 2}","handlingStrategy":"validation","validationCode":"for i, r in enumerate(rules):\n    if \"model\" not in r and \"model_contains\" not in r:\n        raise SystemExit(f\"rule[{i}]: needs model or model_contains\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember resolution and device-memory fields are filters, not selectors; a rule always needs a model selector"],"tags":["config","batching","validation","selector"],"backgroundTag":"missing-required-config-field","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}