{"record":{"id":"644acd7ada76f9d9","repo":"prestodb/presto","slug":"values-length-is-less-than-positioncount-644acd","errorCode":null,"errorMessage":"values length is less than positionCount","messagePattern":"values length is less than positionCount","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/block/Int128ArrayBlock.java","lineNumber":74,"sourceCode":"\n    public Int128ArrayBlock(int positionCount, Optional<boolean[]> valueIsNull, long[] values)\n    {\n        this(0, positionCount, valueIsNull.orElse(null), values);\n    }\n\n    Int128ArrayBlock(int positionOffset, int positionCount, boolean[] valueIsNull, long[] values)\n    {\n        if (positionOffset < 0) {\n            throw new IllegalArgumentException(\"positionOffset is negative\");\n        }\n        this.positionOffset = positionOffset;\n        if (positionCount < 0) {\n            throw new IllegalArgumentException(\"positionCount is negative\");\n        }\n        this.positionCount = positionCount;\n\n        if (values.length - (positionOffset * 2) < positionCount * 2) {\n            throw new IllegalArgumentException(\"values length is less than positionCount\");\n        }\n        this.values = values;\n\n        if (valueIsNull != null && valueIsNull.length - positionOffset < positionCount) {\n            throw new IllegalArgumentException(\"isNull length is less than positionCount\");\n        }\n        this.valueIsNull = valueIsNull;\n\n        retainedSizeInBytes = INSTANCE_SIZE + sizeOf(valueIsNull) + sizeOf(values);\n    }\n\n    @Override\n    public long getSizeInBytes()\n    {\n        return SIZE_IN_BYTES_PER_POSITION * (long) positionCount;\n    }\n\n    @Override","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/Int128ArrayBlock.java#L56-L92","documentation":"Int128 values occupy 2 longs each, so the values array must hold at least positionCount*2 longs beyond the positionOffset (which is also in positions, i.e. offset*2 longs). The constructor throws IllegalArgumentException when the backing array is too small, preventing out-of-bounds reads later.","triggerScenarios":"new Int128ArrayBlock(positionOffset, positionCount, valueIsNull, values) where values.length - positionOffset*2 < positionCount*2 — e.g. allocating values as positionCount longs instead of 2*positionCount, or forgetting to account for a non-zero positionOffset.","commonSituations":"Custom block builders allocating 1 long per position instead of 2 for 128-bit types (DECIMAL(38,x)); reusing buffers trimmed to a smaller previous batch; slicing code that applies the offset to positions but not to the array length calculation.","solutions":["Allocate values with capacity 2 * (positionOffset + positionCount) longs.","Double-check every allocation site for Int128 blocks multiplies the position count by 2 (INT128 = two longs).","If reusing a buffer, grow it (Arrays.copyOf) when values.length < 2 * (positionOffset + positionCount)."],"exampleFix":"// before\nlong[] values = new long[positionCount]; // too small for 128-bit values\n// after\nlong[] values = new long[2 * (positionOffset + positionCount)];","handlingStrategy":"validation","validationCode":"checkArgument(values.length >= 2 * (positionOffset + positionCount),\n    \"values array too small: need %d longs for %d INT128 positions, got %d\",\n    2 * (positionOffset + positionCount), positionCount, values.length);","typeGuard":"boolean valuesSizedForInt128(long[] values, int positionOffset, int positionCount) {\n    return values.length >= 2 * (positionOffset + positionCount);\n}","tryCatchPattern":"try {\n    block = new Int128ArrayBlock(offset, count, isNull, values);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"values length is less than positionCount\")) {\n        values = Arrays.copyOf(values, 2 * (offset + count));\n        block = new Int128ArrayBlock(offset, count, isNull, values);\n    } else { throw e; }\n}","preventionTips":["Remember INT128 needs 2 longs per position — multiply by 2 in every allocation.","Centralize Int128 buffer allocation in one helper to avoid per-site mistakes.","Check that reused/grown buffers account for positionOffset as well as positionCount."],"tags":["presto","block","buffer-size","int128","constructor-validation"],"backgroundTag":"buffer-too-small","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}