{"record":{"id":"220aa710e08b71c1","repo":"elastic/elasticsearch","slug":"distances-array-must-have-length-4-but-was-220aa7","errorCode":null,"errorMessage":"distances array must have length 4, but was: {}","messagePattern":"distances array must have length 4, but was: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/simdvec/src/main/java/org/elasticsearch/simdvec/ESVectorUtil.java","lineNumber":322,"sourceCode":"\n    /**\n     * Bulk computation of square distances from a sub-range of a byte query vector to four byte candidate vectors.\n     */\n    public static void squareDistanceBulk(\n        byte[] q,\n        int qOffset,\n        int length,\n        byte[] v0,\n        byte[] v1,\n        byte[] v2,\n        byte[] v3,\n        float[] distances\n    ) {\n        if (q.length != v0.length || q.length != v1.length || q.length != v2.length || q.length != v3.length) {\n            throw new IllegalArgumentException(\"vector dimensions incompatible\");\n        }\n        if (distances.length != 4) {\n            throw new IllegalArgumentException(\"distances array must have length 4, but was: \" + distances.length);\n        }\n        Objects.checkFromIndexSize(qOffset, length, q.length);\n        IMPL.squareDistanceBulk(q, qOffset, v0, v1, v2, v3, 0, distances, length);\n    }\n\n    /**\n     * Bulk computation of dot product from a byte query vector to four byte candidate vectors.\n     */\n    public static void dotProductBulk(byte[] q, byte[] v0, byte[] v1, byte[] v2, byte[] v3, int distancesOffset, float[] distances) {\n        if (q.length != v0.length || q.length != v1.length || q.length != v2.length || q.length != v3.length) {\n            throw new IllegalArgumentException(\"vector dimensions incompatible\");\n        }\n        if (distances.length < 4) {\n            throw new IllegalArgumentException(\"distances array must have length >= 4, but was: \" + distances.length);\n        }\n        if (distancesOffset < 0 || distancesOffset > distances.length - 4) {\n            throw new IllegalArgumentException(\"distancesOffset must be between 0 and distances.length - 4\");\n        }","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/simdvec/src/main/java/org/elasticsearch/simdvec/ESVectorUtil.java#L304-L340","documentation":"Thrown by the windowed overload squareDistanceBulk(q, qOffset, length, v0..v3, distances) when distances.length != 4. Unlike the sibling overload that accepts distances.length >= 4 with an explicit distancesOffset, THIS overload requires the output array to be EXACTLY length 4 because it always writes four consecutive results at index 0. Reusing a larger scratch buffer from the other overload will trip this.","triggerScenarios":"Calling the windowed squareDistanceBulk with a distances array of any length other than 4 — including a larger scratch buffer intended for the offset-based overload, or a smaller single-result buffer.","commonSituations":"Sharing scratch buffers between the two squareDistanceBulk overloads; allocating dist from a pool whose default capacity is not exactly 4; refactoring between overloads without resizing the output array.","solutions":["Allocate a dedicated float[4] for the windowed overload — do not share with the offset overload.","If you need a larger reusable scratch, call the (q, v0..v3, distancesOffset, distances) overload instead and pass offset 0.","Add an assertion at scorer construction that the supplied distances array is exactly length 4 for this code path."],"exampleFix":"// before\nfloat[] dist = sharedScratch; // length 8, used by the offset overload too\nESVectorUtil.squareDistanceBulk(q, qOff, len, v0, v1, v2, v3, dist); // IAE\n\n// after\nfloat[] dist4 = new float[4];\nESVectorUtil.squareDistanceBulk(q, qOff, len, v0, v1, v2, v3, dist4);","handlingStrategy":"validation","validationCode":"if (distances.length != 4) {\n    throw new IllegalArgumentException(\"windowed squareDistanceBulk requires distances.length == 4, got \" + distances.length);\n}\nESVectorUtil.squareDistanceBulk(q, qOffset, length, v0, v1, v2, v3, distances);","typeGuard":null,"tryCatchPattern":"try {\n    ESVectorUtil.squareDistanceBulk(q, qOff, len, v0, v1, v2, v3, dist);\n} catch (IllegalArgumentException e) {\n    throw new QueryException(\"windowed squareDistanceBulk distances length must be 4\", e);\n}","preventionTips":["Do NOT share scratch between the offset overload (>=4 allowed) and this exact-4 overload.","Allocate a dedicated float[4] for this code path.","If you need a larger reusable scratch, call the (q, v0..v3, distancesOffset, distances) overload instead with offset 0."],"tags":["vector","simd","bulk","scratch-buffer","square-distance","api-pitfall","elasticsearch"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}