{"record":{"id":"0c9444289e9a2bd9","repo":"sgl-project/sglang","slug":"bs-key-candidate-steps-must-be-a-list-of-non-ne","errorCode":null,"errorMessage":"BS {key}: candidate_steps must be a list of non-negative ints, got {steps!r}","messagePattern":"BS (.+?): candidate_steps must be a list of non-negative ints, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/speculative/adaptive_spec_params.py","lineNumber":114,"sourceCode":"    \"\"\"\n    if cfg_path is not None:\n        with open(cfg_path) as f:\n            cfg = json.load(f)\n    else:\n        cfg = DEFAULT_ADAPTIVE_CONFIG\n\n    bs_entries: dict[int, dict] = {}\n    for key, entry in cfg.items():\n        if not key.isdigit():\n            continue\n\n        steps = entry.get(\"candidate_steps\")\n        if (\n            not isinstance(steps, list)\n            or not steps\n            or not all(isinstance(s, int) and s >= 0 for s in steps)\n        ):\n            raise ValueError(\n                f\"BS {key}: candidate_steps must be a list of non-negative ints, \"\n                f\"got {steps!r}\"\n            )\n        bs_entries[int(key)] = entry\n\n    if not bs_entries:\n        raise ValueError(\n            \"speculative_adaptive_config must contain at least one integer-string \"\n            'BS key, e.g. {\"1\": {\"candidate_steps\": [1,3,7]}}. '\n            f\"Got keys: {list(cfg.keys())}\"\n        )\n    return cfg, bs_entries\n\n\ndef resolve_candidate_steps_from_config(\n    cfg_path: str | None = None,\n) -> list[int]:\n    \"\"\"Union of every BS slot's candidate steps; sizes the runtime buffers.\"\"\"","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/speculative/adaptive_spec_params.py#L96-L132","documentation":"Validating the speculative_adaptive_config: a batch-size entry's candidate_steps field must be a non-empty list of non-negative integers. Anything else (missing key, empty list, floats, strings, negatives) is rejected.","triggerScenarios":"A BS entry whose candidate_steps is absent, [], contains floats/strings/negative numbers, or is not a list at all.","commonSituations":"Hand-editing the adaptive config JSON and using floats (3.0), strings (\"3\"), or forgetting the field; YAML-to-JSON conversion artifacts.","solutions":["Fix the entry so candidate_steps is a non-empty list of non-negative ints","Validate the config JSON before passing it to the server"],"exampleFix":"# before\n{\"4\": {\"candidate_steps\": [1, 3.0, \"7\"]}}\n# after\n{\"4\": {\"candidate_steps\": [1, 3, 7]}}","handlingStrategy":"type-guard","validationCode":"def ok_steps(s):\n    return isinstance(s, list) and len(s) > 0 and all(isinstance(x, int) and not isinstance(x, bool) and x >= 0 for x in s)\nassert all(ok_steps(e.get('candidate_steps')) for e in cfg.values())","typeGuard":"def is_valid_candidate_steps(v) -> bool:\n    return isinstance(v, list) and bool(v) and all(isinstance(x, int) and not isinstance(x, bool) and x >= 0 for x in v)","tryCatchPattern":null,"preventionTips":["Write configs with plain ints, no quotes or decimals","Validate config JSON with a schema checker before launch"],"tags":["sglang","speculative-decoding","config-validation","adaptive"],"backgroundTag":"schema-validation-failed","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}