{"record":{"id":"05d1d499769a89a2","repo":"prestodb/presto","slug":"offsets-length-is-less-than-positioncount-05d1d4","errorCode":null,"errorMessage":"offsets length is less than positionCount","messagePattern":"offsets length is less than positionCount","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/block/VariableWidthBlock.java","lineNumber":85,"sourceCode":"\n    VariableWidthBlock(int arrayOffset, int positionCount, Slice slice, int[] offsets, boolean[] valueIsNull)\n    {\n        if (arrayOffset < 0) {\n            throw new IllegalArgumentException(\"arrayOffset is negative\");\n        }\n        this.arrayOffset = arrayOffset;\n        if (positionCount < 0) {\n            throw new IllegalArgumentException(\"positionCount is negative\");\n        }\n        this.positionCount = positionCount;\n\n        if (slice == null) {\n            throw new IllegalArgumentException(\"slice is null\");\n        }\n        this.slice = slice;\n\n        if (offsets.length - arrayOffset < (positionCount + 1)) {\n            throw new IllegalArgumentException(\"offsets length is less than positionCount\");\n        }\n        this.offsets = offsets;\n\n        if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {\n            throw new IllegalArgumentException(\"valueIsNull length is less than positionCount\");\n        }\n        this.valueIsNull = valueIsNull;\n\n        sizeInBytes = offsets[arrayOffset + positionCount] - offsets[arrayOffset] + ((Integer.BYTES + Byte.BYTES) * (long) positionCount);\n        retainedSizeInBytes = INSTANCE_SIZE + slice.getRetainedSize() + sizeOf(valueIsNull) + sizeOf(offsets);\n    }\n\n    @Override\n    public final int getPositionOffset(int position)\n    {\n        return offsets[position + arrayOffset];\n    }\n","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/VariableWidthBlock.java#L67-L103","documentation":"The offsets array must contain positionCount + 1 entries starting at arrayOffset (offsets[i] and offsets[i+1] delimit each value). If offsets.length - arrayOffset < positionCount + 1 there are not enough boundary entries to decode every position, so the constructor throws IllegalArgumentException.","triggerScenarios":"Constructing VariableWidthBlock with an offsets array shorter than arrayOffset + positionCount + 1; typical when positionCount was computed from data length but offsets came from a truncated or differently-sized page.","commonSituations":"Corrupt/truncated serialized pages; mixing offsets arrays between blocks with different position counts; off-by-one when building offsets manually (forgetting the final sentinel entry).","solutions":["Ensure offsets has at least arrayOffset + positionCount + 1 entries (include the trailing sentinel).","Verify positionCount matches the offsets array actually passed, not a different block's.","Check the serialization/read path for truncation producing short offsets arrays."],"exampleFix":"// before\nint[] offsets = new int[positions.length]; // missing trailing entry\nnew VariableWidthBlock(0, positions.length, slice, offsets, null);\n// after\nint[] offsets = new int[positions.length + 1]; // +1 sentinel\nnew VariableWidthBlock(0, positions.length, slice, offsets, null);","handlingStrategy":"validation","validationCode":"checkState(offsets.length - arrayOffset >= positionCount + 1,\n    \"offsets too short: need %s, have %s\", positionCount + 1 + arrayOffset, offsets.length);","typeGuard":null,"tryCatchPattern":"try {\n    new VariableWidthBlock(arrayOffset, positionCount, slice, offsets, valueIsNull);\n} catch (IllegalArgumentException e) {\n    // inspect page truncation / mismatched offsets source\n}","preventionTips":["Always include the trailing sentinel entry in offsets arrays","Keep offsets and positionCount derived from the same page read","Detect truncated serialized pages before block construction"],"tags":["presto","block","illegal-argument","offsets-array"],"backgroundTag":"block-constructor-validation","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"}