{"record":{"id":"9c0fe3d3f7b327fd","repo":"vllm-project/vllm","slug":"numa-bind-cpus-must-not-be-empty","errorCode":null,"errorMessage":"numa_bind_cpus must not be empty.","messagePattern":"numa_bind_cpus must not be empty\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"vllm/config/parallel.py","lineNumber":431,"sourceCode":"\n    @field_validator(\"numa_bind_nodes\")\n    @classmethod\n    def _validate_numa_bind_nodes(cls, value: list[int] | None) -> list[int] | None:\n        if value is None:\n            return None\n        if not value:\n            raise ValueError(\"numa_bind_nodes must not be empty.\")\n        if any(node < 0 for node in value):\n            raise ValueError(\"numa_bind_nodes must contain non-negative integers.\")\n        return value\n\n    @field_validator(\"numa_bind_cpus\")\n    @classmethod\n    def _validate_numa_bind_cpus(cls, value: list[str] | None) -> list[str] | None:\n        if value is None:\n            return None\n        if not value:\n            raise ValueError(\"numa_bind_cpus must not be empty.\")\n\n        for cpuset in value:\n            if not cpuset:\n                raise ValueError(\"numa_bind_cpus entries must not be empty.\")\n            if not _NUMACTL_CPUSET_PATTERN.fullmatch(cpuset):\n                raise ValueError(\n                    \"numa_bind_cpus entries must use numactl CPU list syntax, \"\n                    \"for example '0-3' or '0,2,4-7'.\"\n                )\n            for part in cpuset.split(\",\"):\n                if \"-\" not in part:\n                    continue\n                start_str, end_str = part.split(\"-\", 1)\n                if int(start_str) > int(end_str):\n                    raise ValueError(\n                        f\"numa_bind_cpus ranges must be ascending, but got '{cpuset}'.\"\n                    )\n        return value","sourceCodeStart":413,"sourceCodeEnd":449,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/vllm/config/parallel.py#L413-L449","documentation":"ParallelConfig's field validator for numa_bind_cpus mirrors the nodes validator: None means unset, but an explicitly empty list is rejected because binding to zero CPU sets is meaningless. Each list entry is a numactl CPU-list string.","triggerScenarios":"Passing --numa-bind-cpus with an empty value that parses to []; template interpolation of an empty env var; Python code ParallelConfig(numa_bind_cpus=[]).","commonSituations":"Same templating failure as numa_bind_nodes: charts/scripts emitting the flag unconditionally with an empty variable.","solutions":["Omit --numa-bind-cpus when CPU pinning is not wanted.","Otherwise pass at least one numactl CPU list, e.g. --numa-bind-cpus 0-3.","Guard the flag in your launch template: only render it when the variable is non-empty."],"exampleFix":"# before\nvllm serve model --numa-bind-cpus \"${CPUS}\"  # CPUS=\"\" -> []\n\n# after\nvllm serve model --numa-bind-cpus 0-3,8-11","handlingStrategy":"validation","validationCode":"def normalize_numa_cpus(v: list[str] | None) -> list[str] | None:\n    return None if not v else v","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only render --numa-bind-cpus when the CPU variable is non-empty.","Use None (omit) rather than [] to mean 'no CPU pinning'."],"tags":["vllm","config","numa","cpuset","validation"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}