{"record":{"id":"7de8dac02bf17072","repo":"sgl-project/sglang","slug":"num-instances-must-be-1-got-num-instances","errorCode":null,"errorMessage":"num_instances must be >= 1, got {num_instances}","messagePattern":"num_instances must be >= 1, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/disaggregation/dispatch_policy.py","lineNumber":14,"sourceCode":"# SPDX-License-Identifier: Apache-2.0\n\"\"\"Dispatch policies for multi-instance disaggregated diffusion pipelines.\"\"\"\n\nimport abc\nimport logging\nimport threading\n\nlogger = logging.getLogger(__name__)\n\n\nclass DispatchPolicy(abc.ABC):\n    def __init__(self, num_instances: int):\n        if num_instances < 1:\n            raise ValueError(f\"num_instances must be >= 1, got {num_instances}\")\n        self._num_instances = num_instances\n\n    @property\n    def num_instances(self) -> int:\n        return self._num_instances\n\n    @abc.abstractmethod\n    def select(self, active_counts: list[int] | None = None) -> int: ...\n\n    def select_with_capacity(self, free_slots: list[int]) -> int | None:\n        \"\"\"Select an instance that has free capacity, or None if all full.\"\"\"\n        if not any(s > 0 for s in free_slots):\n            return None\n        return self.select(active_counts=None)\n\n    def record_completion(self, instance_id: int) -> None:\n        pass\n","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/disaggregation/dispatch_policy.py#L1-L32","documentation":"Thrown by the DispatchPolicy base-class constructor when num_instances is less than 1. Dispatch policies (round_robin, max_free_slots) distribute requests across a fixed set of instances, so at least one instance is required for the policy to be meaningful.","triggerScenarios":"Instantiating any DispatchPolicy subclass (directly or via create_dispatch_policy) with num_instances=0 or a negative number — typically because the instance list/config used to compute num_instances was empty.","commonSituations":"Starting a disaggregated multimodal runtime with zero encoder or denoiser instances registered, an empty instance config file, or an off-by-one/len() of an empty list feeding num_instances.","solutions":["Ensure at least one encoder/denoiser instance is configured and registered before constructing the dispatch policy","Log/validate the instance list length at startup and fail early with a clear message when it is empty","Check that the config key feeding num_instances (instance endpoints/hosts list) is populated and parsed correctly"],"exampleFix":"# before\npolicy = RoundRobin(num_instances=len(instances))  # len==0 -> ValueError\n\n# after\nassert instances, \"at least one instance must be configured\"\npolicy = RoundRobin(num_instances=max(1, len(instances)))","handlingStrategy":"validation","validationCode":"if not instances or len(instances) < 1:\n    raise ConfigError(\"disaggregation requires at least one instance\")\npolicy = create_dispatch_policy(name=policy_name, num_instances=len(instances), **kwargs)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate the instance list is non-empty at startup before building dispatch policies","Fail fast with a descriptive message when service discovery returns zero instances","Add config schema checks that reject empty instance arrays"],"tags":["disaggregation","dispatch-policy","config-validation","empty-instances"],"backgroundTag":"invalid-config-value","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}