{"record":{"id":"fcbcf5eaec32af76","repo":"sgl-project/sglang","slug":"speculative-adaptive-config-must-contain-at-least","errorCode":null,"errorMessage":"speculative_adaptive_config must contain at least one integer-string BS key, e.g. {\"1\": {\"candidate_steps\": [1,3,7]}}. Got keys: {list(cfg.keys())}","messagePattern":"speculative_adaptive_config must contain at least one integer-string BS key, e\\.g\\. (.+?)\\}\\. Got keys: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/speculative/adaptive_spec_params.py","lineNumber":121,"sourceCode":"    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.\"\"\"\n    _, bs_entries = _load_adaptive_config(cfg_path)\n    all_steps: set[int] = set()\n    for entry in bs_entries.values():\n        all_steps.update(entry[\"candidate_steps\"])\n    return sorted(all_steps)\n\n","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/speculative/adaptive_spec_params.py#L103-L139","documentation":"Validating speculative_adaptive_config: after scanning keys, no entry had an integer-string batch-size key. The config must be a dict keyed by BS as strings that parse to ints, e.g. {\"1\": {...}}.","triggerScenarios":"Passing an empty dict, or a dict whose keys are not integer strings (e.g. {\"default\": ...}, {\"bs_8\": ...}, or integer keys already parsed as ints by JSON/YAML loading).","commonSituations":"Using non-string keys in a YAML config that loads as ints; naming keys by label instead of batch size; passing the wrong structure entirely.","solutions":["Rewrite the config with integer-string keys: {\"1\": {\"candidate_steps\": [1,3,7]}, \"8\": {...}}","If loading via YAML/JSON where keys become ints, serialize to a dict with str(k) keys first"],"exampleFix":"# before\nspeculative_adaptive_config = {8: {\"candidate_steps\": [1, 3]}}\n# after\nspeculative_adaptive_config = {\"8\": {\"candidate_steps\": [1, 3]}}","handlingStrategy":"type-guard","validationCode":"assert isinstance(cfg, dict) and cfg and all(k.isdigit() for k in cfg), f'keys must be integer strings, got {list(cfg)}'","typeGuard":"def is_valid_bs_keys(cfg) -> bool:\n    return isinstance(cfg, dict) and len(cfg) > 0 and all(isinstance(k, str) and k.isdigit() for k in cfg.keys())","tryCatchPattern":null,"preventionTips":["Normalize config keys with str(k) after YAML loads them as ints","Use the documented {\"1\": {\"candidate_steps\": [...]}} shape verbatim"],"tags":["sglang","speculative-decoding","config-validation","adaptive","key-format"],"backgroundTag":"schema-validation-failed","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}