{"record":{"id":"fe368dcba780ce5c","repo":"ruvnet/ruflo","slug":"flashattention-keys-and-values-must-have-same-cou","errorCode":null,"errorMessage":"FlashAttention: Keys and values must have same count. Got ${keys.length} keys, ${values.length} values","messagePattern":"FlashAttention: Keys and values must have same count\\. Got (.+?) keys, (.+?) values","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/neural/src/flash-attention.ts","lineNumber":775,"sourceCode":"    }\n\n    return vectors;\n  }\n\n  /**\n   * Validate input arrays\n   */\n  private validateInputs(\n    queries: Float32Array[],\n    keys: Float32Array[],\n    values: Float32Array[],\n  ): void {\n    if (!queries.length || !keys.length || !values.length) {\n      throw new Error('FlashAttention: Empty input arrays');\n    }\n\n    if (keys.length !== values.length) {\n      throw new Error(\n        `FlashAttention: Keys and values must have same count. Got ${keys.length} keys, ${values.length} values`,\n      );\n    }\n\n    const qDim = queries[0]?.length ?? 0;\n    const kDim = keys[0]?.length ?? 0;\n    const vDim = values[0]?.length ?? 0;\n\n    if (qDim !== kDim) {\n      throw new Error(\n        `FlashAttention: Query and key dimensions must match. Got Q=${qDim}, K=${kDim}`,\n      );\n    }\n\n    if (kDim !== vDim) {\n      throw new Error(\n        `FlashAttention: Key and value dimensions must match. Got K=${kDim}, V=${vDim}`,\n      );","sourceCodeStart":757,"sourceCodeEnd":793,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/neural/src/flash-attention.ts#L757-L793","documentation":"Attention scores every query against every key and mixes the corresponding value, so keys and values must be parallel arrays of the same length; validateInputs() enforces keys.length === values.length and reports both counts when they differ. A mismatch means K and V were built from different sequences — an off-by-one, a bad slice, or caching one side from a previous step.","triggerScenarios":"Building keys from one window and values from another (e.g. keys.slice(0, n) vs values.slice(1, n+1)); concatenating past-sequence keys for KV-cache without extending values the same way; example code adapted with different dummy lengths.","commonSituations":"Sliding-window/KV-cache attention implementations; inconsistent preprocessing of the same token stream; partial refactors that update one array's construction.","solutions":["Derive keys and values from the same source array so lengths match by construction","Assert keys.length === values.length before calling computeAttention","Re-check slice bounds: both must use the same [i, i+n) window"],"exampleFix":"// before\nconst out = computeAttention(q, cachedKeys, freshValues);\n\n// after\nif (keys.length !== values.length) {\n  throw new Error(`K/V count mismatch: ${keys.length} vs ${values.length} - rebuild both from the same window`);\n}\nconst out = computeAttention(q, keys, values);","handlingStrategy":"validation","validationCode":"if (keys.length !== values.length) {\n  throw new Error(\n    `K/V count mismatch: ${keys.length} keys vs ${values.length} values - rebuild both from the same window`,\n  );\n}\nconst out = computeAttention(queries, keys, values);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive keys and values from the same array so counts match by construction","Keep KV-cache extensions symmetric: append to K and V together","Use identical slice windows for K and V in sliding-window code"],"tags":["neural","flash-attention","input-shape","validation"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}