{"record":{"id":"5f6d659bbdb86823","repo":"elastic/elasticsearch","slug":"bit-must-be-between-1-and-8-but-was","errorCode":null,"errorMessage":"bit must be between 1 and 8, but was: {}","messagePattern":"bit must be between 1 and 8, but was: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/simdvec/src/main/java/org/elasticsearch/simdvec/ESVectorUtil.java","lineNumber":685,"sourceCode":"    }\n\n    /**\n     * Optimized-scalar quantization of the provided vector to the provided destination array.\n     *\n     * @param vector the vector to quantize\n     * @param destination the array to store the result\n     * @param lowInterval the minimum value, lower values in the original array will be replaced by this value\n     * @param upperInterval the maximum value, bigger values in the original array will be replaced by this value\n     * @param bit the number of bits to use for quantization, must be between 1 and 8\n     *\n     * @return return the sum of all the elements of the resulting quantized vector.\n     */\n    public static int quantizeVectorWithIntervals(float[] vector, int[] destination, float lowInterval, float upperInterval, byte bit) {\n        if (vector.length > destination.length) {\n            throw new IllegalArgumentException(\"vector dimensions differ: \" + vector.length + \"!=\" + destination.length);\n        }\n        if (bit <= 0 || bit > Byte.SIZE) {\n            throw new IllegalArgumentException(\"bit must be between 1 and 8, but was: \" + bit);\n        }\n        return IMPL.quantizeVectorWithIntervals(vector, destination, lowInterval, upperInterval, bit);\n    }\n\n    /**\n     * Bulk computation of square distances between a query vector and four vectors.Result is stored in the provided distances array.\n     *\n     * @param q the query vector\n     * @param v0 the first vector\n     * @param v1 the second vector\n     * @param v2 the third vector\n     * @param v3 the fourth vector\n     * @param distancesOffset offset to the location in the distances array where we want to store the 4 results,\n     *                        we require distancesOffset to be between 0 and distances.length - 4\n     * @param distances an array to store the computed square distances, must have length >= 4\n     *\n     * @throws IllegalArgumentException if the dimensions of the vectors do not match or if the distances array does not have length 4\n     */","sourceCodeStart":667,"sourceCodeEnd":703,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/simdvec/src/main/java/org/elasticsearch/simdvec/ESVectorUtil.java#L667-L703","documentation":"Thrown by quantizeVectorWithIntervals when the bit parameter is outside the inclusive range [1, 8]. OSQ supports 1 to 8 bits per quantized value because the destination is int-backed and the SIMD kernel operates on byte-wide lanes. The guard rejects zero, negative, or >8 bit depths before they corrupt the quantization grid.","triggerScenarios":"Calling ESVectorUtil.quantizeVectorWithIntervals(float[], int[], float, float, byte bit) with bit <= 0 or bit > 8. Happens when the OSQ configuration is read from a mapping or setting that allows an out-of-range bits value, or when a default byte (signed) carrying -1 leaks into the bit parameter.","commonSituations":"OSQ bits setting misconfigured to 0 or 9+; signed byte overflow where a value like 0xFF (-1) is passed as bit; index setting inherited from a template with an invalid bits value; upgrade that introduced a new default bits value not yet validated at the mapping layer.","solutions":["Validate that bit is between 1 and 8 inclusive before calling; clamp or reject at the configuration layer.","Check the OSQ bits setting in the index mapping / index settings and correct it to a value in [1, 8].","If bit arrives as a signed byte from a wider field, mask and range-check it before passing to this API."],"exampleFix":"// before\nint sum = ESVectorUtil.quantizeVectorWithIntervals(vector, destination, low, upper, bits);\n// after\nif (bits <= 0 || bits > Byte.SIZE) {\n    throw new IllegalArgumentException(\"OSQ bits must be 1..8, got \" + bits);\n}\nint sum = ESVectorUtil.quantizeVectorWithIntervals(vector, destination, low, upper, bits);","handlingStrategy":"validation","validationCode":"if (bit <= 0 || bit > Byte.SIZE) {\n    throw new IllegalArgumentException(\"OSQ bits must be 1..8, got \" + bit);\n}\nint sum = ESVectorUtil.quantizeVectorWithIntervals(vector, destination, lowInterval, upperInterval, bit);","typeGuard":"static boolean isValidOsqBits(byte bit) {\n    return bit > 0 && bit <= Byte.SIZE;\n}","tryCatchPattern":null,"preventionTips":["Validate the OSQ bits setting at the mapping/configuration layer, not only at the SIMD boundary.","Range-check any signed byte that flows into the bit parameter to catch overflow (-1 from 0xFF).","Document the valid range [1, 8] in index settings tooltips and error messages."],"tags":["vector","osq","quantization","config","argument-validation"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}