{"record":{"id":"c35ce4465bed6f6a","repo":"prestodb/presto","slug":"isnull-length-is-less-than-positioncount-c35ce4","errorCode":null,"errorMessage":"isNull length is less than positionCount","messagePattern":"isNull 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":79,"sourceCode":"\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\n    public OptionalInt fixedSizeInBytesPerPosition()\n    {\n        return OptionalInt.of(SIZE_IN_BYTES_PER_POSITION);\n    }\n","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/Int128ArrayBlock.java#L61-L97","documentation":"The optional null bitmap must cover every position the block exposes: valueIsNull.length - positionOffset must be >= positionCount. The constructor throws IllegalArgumentException when the isNull array is shorter than the visible position range.","triggerScenarios":"Passing a valueIsNull array sized for the original block but a positionOffset/positionCount describing a larger region; allocating valueIsNull as positionCount while using a nonzero positionOffset; passing an array trimmed by a previous compaction.","commonSituations":"Region/view construction where isNull was sliced but positions were not (or vice versa); page serialization round-trips that shrink the null channel; building blocks from columns of mismatched lengths.","solutions":["Size valueIsNull as positionOffset + positionCount booleans, matching the values array's position coverage.","When creating a region, slice valueIsNull with the same offset logic used for positions (Arrays.copyOfRange(valueIsNull, offset, offset + count)).","Validate column-array lengths are equal before constructing the block."],"exampleFix":"// before\nboolean[] valueIsNull = new boolean[positionCount]; // ignores positionOffset\n// after\nboolean[] valueIsNull = new boolean[positionOffset + positionCount];","handlingStrategy":"validation","validationCode":"if (valueIsNull != null) {\n    checkArgument(valueIsNull.length >= positionOffset + positionCount,\n        \"isNull array too small: need %d, got %d\", positionOffset + positionCount, valueIsNull.length);\n}","typeGuard":"boolean nullBitmapCovers(boolean[] valueIsNull, int positionOffset, int positionCount) {\n    return valueIsNull == null || valueIsNull.length >= positionOffset + positionCount;\n}","tryCatchPattern":"try {\n    block = new Int128ArrayBlock(offset, count, isNull, values);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"isNull length is less than positionCount\")) {\n        isNull = Arrays.copyOfRange(isNull, 0, offset + count); // pad and retry\n        block = new Int128ArrayBlock(offset, count, isNull, values);\n    } else { throw e; }\n}","preventionTips":["Slice isNull arrays with the same offset/length used for positions when building regions.","Assert all per-column arrays (values, isNull) have matching lengths before constructing blocks.","Never trim the null channel independently of the value channel."],"tags":["presto","block","null-bitmap","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"}