{"record":{"id":"51c65df71581d42f","repo":"ruvnet/ruflo","slug":"flashattention-query-and-key-dimensions-must-matc","errorCode":null,"errorMessage":"FlashAttention: Query and key dimensions must match. Got Q=${qDim}, K=${kDim}","messagePattern":"FlashAttention: Query and key dimensions must match\\. Got Q=(.+?), K=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/neural/src/flash-attention.ts","lineNumber":785,"sourceCode":"    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      );\n    }\n  }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet flashAttentionInstance: FlashAttention | null = null;\n","sourceCodeStart":767,"sourceCodeEnd":803,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/neural/src/flash-attention.ts#L767-L803","documentation":"The QK^T dot product requires query and key vectors of equal dimension; validateInputs() compares the length of queries[0] and keys[0] and throws with both dims on mismatch. Note it inspects only the first vectors — all vectors are assumed uniform within each set, so a single stray vector of another width can also corrupt results without tripping this check.","triggerScenarios":"Queries produced by a different embedding model than keys (e.g. 384-dim Q vs 768-dim K after a model swap); mixing outputs of two encoders; a head_dim config change applied to only one side.","commonSituations":"Upgrading an ONNX embedding model without regenerating cached tensors; mixing fresh and cached embeddings; hand-written test fixtures with mismatched dims.","solutions":["Use the same embedding dimension (same model/config) for queries and keys","Project one side to the other's dimension before calling attention","Log qDim/kDim at startup in adapters that bridge two models"],"exampleFix":"// before\nconst out = computeAttention(queries384, keys768, values768);\n\n// after\n// re-encode queries with the same model as keys (768-dim)\nconst out = computeAttention(queries768, keys768, values768);","handlingStrategy":"validation","validationCode":"const qDim = queries[0]?.length ?? 0;\nconst kDim = keys[0]?.length ?? 0;\nif (qDim !== kDim) {\n  throw new Error(`Q/K dimension mismatch: ${qDim} vs ${kDim} - re-encode with one model`);\n}\nconst out = computeAttention(queries, keys, values);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use one embedding model for queries and keys","Invalidate cached embeddings when the encoder changes","Log tensor dims at adapter boundaries to catch mismatches early"],"tags":["neural","flash-attention","input-shape","embedding-dimension"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}