{"record":{"id":"6cb40f2abae50ec3","repo":"sgl-project/sglang","slug":"dflash-requires-draft-num-hidden-layers-in-config","errorCode":null,"errorMessage":"DFLASH requires draft num_hidden_layers in config. Got config without num_hidden_layers.","messagePattern":"DFLASH requires draft num_hidden_layers in config\\. Got config without num_hidden_layers\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/speculative/dflash_utils.py","lineNumber":543,"sourceCode":"\n@dataclass(frozen=True)\nclass DFlashDraftConfig:\n    num_hidden_layers: Optional[int]\n    num_target_layers: Optional[int]\n    block_size: Optional[int]\n    conv_kernel_size: int\n    conv_group_size: int\n    selector_rank: int\n    selector_top_k: int\n    output_multiplier: float\n    final_logit_softcapping: Optional[float]\n    target_layer_ids: Optional[List[int]]\n    mask_token: str\n    mask_token_id: Optional[int]\n\n    def require_num_layers(self) -> int:\n        if self.num_hidden_layers is None:\n            raise ValueError(\n                \"DFLASH requires draft num_hidden_layers in config. \"\n                \"Got config without num_hidden_layers.\"\n            )\n        return int(self.num_hidden_layers)\n\n    def resolve_block_size(self, *, default: Optional[int] = None) -> Optional[int]:\n        return self.block_size if self.block_size is not None else default\n\n    def resolve_target_layer_ids(\n        self,\n        *,\n        target_num_layers: int,\n        draft_num_layers: Optional[int] = None,\n    ) -> List[int]:\n        target_num_layers = int(target_num_layers)\n        if target_num_layers <= 0:\n            raise ValueError(\n                f\"target_num_layers must be positive, got {target_num_layers}.\"","sourceCodeStart":525,"sourceCodeEnd":561,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/speculative/dflash_utils.py#L525-L561","documentation":"Raised by DFlashDraftConfig.require_num_layers when num_hidden_layers is None. Building DFlash target-layer ids (and resolving aux hidden-state capture points) needs the draft model's layer count; its absence means the draft config never supplied num_hidden_layers. It is an explicit, fail-fast guard against silently guessing a layer layout.","triggerScenarios":"Constructing DFlashDraftConfig without num_hidden_layers (e.g. parsed from a draft config JSON missing the field) and then calling require_num_layers() directly or via resolve_target_layer_ids / _resolve_dflash_aux_hidden_state.","commonSituations":"DFLASH draft config in the HF repo lacks num_hidden_layers; a locally crafted draft config omitted the field; a nested text_config where the layer count lives at a different key and the parser did not find it.","solutions":["Add num_hidden_layers (the draft model's layer count) to the DFLASH draft config.","If the count exists under another key in the HF config, fix the config-reading code/path so it is picked up when building DFlashDraftConfig.","Alternatively pass num_hidden_layers explicitly wherever the config object is constructed."],"exampleFix":"# before\n# draft_config.json: {\"draft_model\": \"...\", \"mask_token\": \"[MASK]\"}  (no num_hidden_layers)\n# after\n# draft_config.json: {\"draft_model\": \"...\", \"mask_token\": \"[MASK]\", \"num_hidden_layers\": 4}","handlingStrategy":"type-guard","validationCode":"if draft_config.num_hidden_layers is None:\n    raise ValueError('DFLASH draft config must include num_hidden_layers')","typeGuard":"def has_num_hidden_layers(cfg) -> bool:\n    return getattr(cfg, 'num_hidden_layers', None) is not None","tryCatchPattern":null,"preventionTips":["Make num_hidden_layers a required key when authoring DFLASH draft configs.","After parsing a draft config, fail fast on missing required fields rather than deferring to layer resolution."],"tags":["speculative-decoding","dflash","missing-config-field"],"backgroundTag":"missing-config-field","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}