{"record":{"id":"5049270d81761dfd","repo":"prestodb/presto","slug":"invalid-position-s-in-block-with-s-positions","errorCode":null,"errorMessage":"Invalid position %s in block with %s positions","messagePattern":"Invalid position (.+?) in block with (.+?) positions","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/block/BlockUtil.java","lineNumber":75,"sourceCode":"\n    static void checkValidRegion(int positionCount, int positionOffset, int length)\n    {\n        if (positionOffset < 0 || length < 0 || positionOffset + length > positionCount) {\n            throw new IndexOutOfBoundsException(format(\"Invalid position %s and length %s in block with %s positions\", positionOffset, length, positionCount));\n        }\n    }\n\n    static void checkValidPositions(boolean[] positions, int positionCount)\n    {\n        if (positions.length != positionCount) {\n            throw new IllegalArgumentException(format(\"Invalid positions array size %d, actual position count is %d\", positions.length, positionCount));\n        }\n    }\n\n    static void checkValidPosition(int position, int positionCount)\n    {\n        if (position < 0 || position >= positionCount) {\n            throw new IllegalArgumentException(format(\"Invalid position %s in block with %s positions\", position, positionCount));\n        }\n    }\n\n    static void checkValidSliceRange(int sourceIndex, int length)\n    {\n        //sourceIndex + length can overflow integer range\n        if (sourceIndex > MAX_ARRAY_SIZE - length) {\n            throw new SliceTooLargeException(format(\"Cannot allocate slice larger than %d bytes\", MAX_ARRAY_SIZE));\n        }\n    }\n\n    static int calculateNewArraySize(int currentSize)\n    {\n        // grow array by 50%\n        long newSize = (long) currentSize + (currentSize >> 1);\n\n        // verify new size is within reasonable bounds\n        if (newSize < DEFAULT_CAPACITY) {","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/BlockUtil.java#L57-L93","documentation":"BlockUtil.checkValidPosition validates a single position index against a block's positionCount, throwing IllegalArgumentException if position is negative or >= positionCount. It protects single-position accessors (isNull, getLong, getSlice, etc.) from reading out of bounds.","triggerScenarios":"Calling block.isNull(pos)/getLong(pos)/getSlice(pos) with a position from a stale row index, from a page that was already consumed/compacted, or from iterating with wrong bounds (e.g. < positionCount+1).","commonSituations":"Operator loops using an off-by-one upper bound; row-number references into blocks that have since been compacted; mixing positions between blocks in a page with differing position counts.","solutions":["Verify 0 <= position < block.getPositionCount() before accessing positions","Ensure the position index belongs to the same block/page that produced it (don't reuse indices across pages)","Catch IllegalArgumentException at the accessor boundary and log position and positionCount"],"exampleFix":"// before\nif (position <= block.getPositionCount()) {\n    value = block.getLong(position);\n}\n// after\nif (position >= 0 && position < block.getPositionCount()) {\n    value = block.getLong(position);\n}","handlingStrategy":"type-guard","validationCode":"checkArgument(position >= 0 && position < block.getPositionCount(), \"position %s out of [0,%s)\", position, block.getPositionCount());","typeGuard":"boolean isValidPosition(Block block, int position) {\n    return position >= 0 && position < block.getPositionCount();\n}","tryCatchPattern":"try {\n    long v = block.getLong(position);\n} catch (IllegalArgumentException e) {\n    throw new PrestoException(GENERIC_INTERNAL_ERROR, \"position \" + position + \" invalid for block of \" + block.getPositionCount(), e);\n}","preventionTips":["Loop with i < block.getPositionCount(), never <=","Do not reuse row indices across different blocks or pages","Check offsets before/after compaction operations that shift positions"],"tags":["java","presto","illegal-argument","block-position"],"backgroundTag":"array-index-out-of-bounds","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"}