{"record":{"id":"3351a5c07f50828e","repo":"sgl-project/sglang","slug":"must-not-be-empty","errorCode":null,"errorMessage":"{} must not be empty","messagePattern":"(.+?) must not be empty","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/mem_cache/storage/umbp/umbp_store.py","lineNumber":119,"sourceCode":"\n\ndef _select_rank_config_value(\n    value: Any,\n    rank_index: int,\n    field_name: str,\n    cast_type,\n    auto_increment_scalar: bool = False,\n):\n    if value is None:\n        raise ValueError(f\"{field_name} must not be None\")\n\n    candidates = value\n    if isinstance(value, str) and \",\" in value:\n        candidates = [item.strip() for item in value.split(\",\") if item.strip()]\n\n    if isinstance(candidates, (list, tuple)):\n        if not candidates:\n            raise ValueError(f\"{field_name} must not be empty\")\n        if rank_index >= len(candidates):\n            raise ValueError(\n                f\"{field_name} has {len(candidates)} entries, but rank_index={rank_index}\"\n            )\n        return cast_type(candidates[rank_index])\n\n    selected = cast_type(candidates)\n    if auto_increment_scalar:\n        selected = cast_type(selected + rank_index)\n    return selected\n\n\n# extra_config is an explicit allow-list grouped by the scope in which each key\n# takes effect (distributed mode is enabled by master_address). Advanced SPDK\n# knobs outside this list go through the \"spdk_passthrough\" escape hatch.\n_COMMON_EXTRA_KEYS = frozenset(\n    {\n        \"dram_capacity_bytes\",","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/mem_cache/storage/umbp/umbp_store.py#L101-L137","documentation":"A rank-scoped config field was given an empty list/tuple (or a comma string with no non-empty items); at least one entry is required so each rank can select one.","triggerScenarios":"Passing an empty list, (), or a string like ',' for a per-rank field (value parsed into zero candidates).","commonSituations":"Programmatically generated per-rank lists ending up empty (e.g. [x for x in ... where the source list was empty); JSON config with an empty array.","solutions":["Populate the list with one entry per rank (or a single scalar)","If generating lists dynamically, guard against empty results and provide a default"],"exampleFix":"# before\nextra['numa_nodes'] = [n for n in detected if n]  # -> []\n# after\nextra['numa_nodes'] = [n for n in detected if n] or [0]","handlingStrategy":"validation","validationCode":"def rank_list(v):\n    if isinstance(v, str):\n        v = [s.strip() for s in v.split(',') if s.strip()]\n    return list(v) if isinstance(v, (list, tuple)) else [v]\nassert rank_list(extra['ssd_paths']), 'field must not be empty'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default empty generated lists to a sensible single value","Fail fast on empty per-rank lists in config validation"],"tags":["umbp","config-validation","empty-list"],"backgroundTag":"config-validation-failed","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}