{"record":{"id":"c5fa7fa0cc4d44ce","repo":"sgl-project/sglang","slug":"a-must-have-shape-b-hv-k-with-hv-hv-k-k","errorCode":null,"errorMessage":"`a` must have shape [B, HV*K] with HV={HV}, K={K} (got a.shape={tuple(a.shape)}).","messagePattern":"`a` must have shape \\[B, HV\\*K\\] with HV=(.+?), K=(.+?) \\(got a\\.shape=(.+?)\\)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/fla/fused_recurrent.py","lineNumber":588,"sourceCode":"    if a.shape[0] != B or b.shape[0] != B:\n        raise ValueError(\n            \"Mismatched batch sizes: \"\n            f\"mixed_qkv.shape[0]={B}, a.shape[0]={a.shape[0]}, b.shape[0]={b.shape[0]}.\"\n        )\n    if ssm_state_indices.shape[0] != B:\n        raise ValueError(\n            f\"`ssm_state_indices` must have shape [B] (got {tuple(ssm_state_indices.shape)}; expected ({B},)).\"\n        )\n\n    if initial_state.ndim != 4:\n        raise ValueError(\n            f\"`initial_state` must be a 4D tensor (got ndim={initial_state.ndim}).\"\n        )\n    if initial_state.stride(-1) != 1:\n        raise ValueError(\"`initial_state` must be contiguous in the last dim.\")\n    HV, V, K = initial_state.shape[-3:]\n    if a.shape[1] != HV * K:\n        raise ValueError(\n            f\"`a` must have shape [B, HV*K] with HV={HV}, K={K} \"\n            f\"(got a.shape={tuple(a.shape)}).\"\n        )\n    if b.shape[1] != HV:\n        raise ValueError(\n            f\"`b` must have shape [B, HV] with HV={HV} (got b.shape={tuple(b.shape)}).\"\n        )\n    if A_log.numel() != HV:\n        raise ValueError(f\"`A_log` must have {HV} elements (got {A_log.numel()}).\")\n    if dt_bias.numel() != HV * K:\n        raise ValueError(\n            f\"`dt_bias` must have {HV * K} elements (got {dt_bias.numel()}).\"\n        )\n    if out.shape != (B, 1, HV, V):\n        raise ValueError(\n            f\"`out` must have shape {(B, 1, HV, V)} (got out.shape={tuple(out.shape)}).\"\n        )\n","sourceCodeStart":570,"sourceCodeEnd":606,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/fla/fused_recurrent.py#L570-L606","documentation":"The gate tensor a must have width HV*K (per value-head, per-key-channel decay inputs). This error fires when a.shape[1] differs, meaning the gating projection width doesn't match the state's head/key config.","triggerScenarios":"a has shape [B, H*K] with H != HV, or [B, HV] (missing the K factor), while initial_state implies HV*K columns.","commonSituations":"Using Q-head-count instead of V-head-count when slicing the a gate from a fused projection; model configs where num_heads != num_v_heads (GQA).","solutions":["Slice/build a with width HV*K from the gating projection","Confirm the split offsets of the fused projection match HV*K and HV","Assert a.shape == (B, HV*K) using dims from initial_state"],"exampleFix":"# before\na = proj[:, :H*K]  # used query heads\n# after\na = proj[:, :HV*K]  # value heads times key dim","handlingStrategy":"validation","validationCode":"HV, V, K = initial_state.shape[-3:]\nassert a.shape == (mixed_qkv.shape[0], HV * K), (a.shape, HV, K)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive split widths from the state config, not from head-count constants","Add a one-time shape check when the gating projection is built"],"tags":["shape-validation","kda","gqa"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}