{"record":{"id":"bccf399ab7ea79d4","repo":"vllm-project/vllm","slug":"numa-bind-nodes-must-not-be-empty","errorCode":null,"errorMessage":"numa_bind_nodes must not be empty.","messagePattern":"numa_bind_nodes must not be empty\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"vllm/config/parallel.py","lineNumber":420,"sourceCode":"\n    fault_tolerance_config: FaultToleranceConfig = Field(\n        default_factory=FaultToleranceConfig\n    )\n    \"\"\"The configurations for fault tolerance.\"\"\"\n\n    @field_validator(\"disable_nccl_for_dp_synchronization\", mode=\"wrap\")\n    @classmethod\n    def _skip_none_validation(cls, value: Any, handler: Callable) -> Any:\n        \"\"\"Skip validation if the value is `None` when initialisation is delayed.\"\"\"\n        return None if value is None else handler(value)\n\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, \"","sourceCodeStart":402,"sourceCodeEnd":438,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/vllm/config/parallel.py#L402-L438","documentation":"ParallelConfig's field validator for numa_bind_nodes treats an explicitly provided empty list as invalid: None means 'not set', but [] would ask the NUMA binding code to bind to zero nodes, which is meaningless. Any non-None value must contain at least one node id.","triggerScenarios":"Passing --numa-bind-nodes with an empty value that parses to [] (e.g. an empty CSV/JSON list), or ParallelConfig(numa_bind_nodes=[]) in Python code; template scripts that interpolate an empty variable into the flag.","commonSituations":"Helm/Kubernetes templates rendering --numa-bind-nodes=\"${NODES}\" where NODES is empty; config generators emitting [] instead of omitting the field.","solutions":["Omit --numa-bind-nodes entirely when you do not want NUMA binding (None is valid and means unset).","Otherwise pass at least one valid node, e.g. --numa-bind-nodes 0 or 0,1.","Fix the templating so empty values drop the flag instead of emitting an empty list."],"exampleFix":"# before (empty env var)\nvllm serve model --numa-bind-nodes \"${NUMA_NODES}\"  # NUMA_NODES=\"\" -> []\n\n# after\n# only add the flag when non-empty:\nvllm serve model --numa-bind-nodes 0,1","handlingStrategy":"validation","validationCode":"def normalize_numa_nodes(v: list[int] | None) -> list[int] | None:\n    return None if not v else v  # drop empty list instead of passing it on","typeGuard":null,"tryCatchPattern":null,"preventionTips":["In launch templates, render --numa-bind-nodes only when the variable is non-empty.","Prefer None over [] to express 'unset' in Python configs."],"tags":["vllm","config","numa","parallel","validation"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}