{"record":{"id":"0646fc2bb0fffe61","repo":"prestodb/presto","slug":"position-is-not-valid-0646fc","errorCode":null,"errorMessage":"position is not valid","messagePattern":"position is not valid","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/block/IntArrayBlock.java","lineNumber":242,"sourceCode":"        return new IntArrayBlock(0, length, newValueIsNull, newValues);\n    }\n\n    @Override\n    public String getEncodingName()\n    {\n        return IntArrayBlockEncoding.NAME;\n    }\n\n    @Override\n    public String toString()\n    {\n        return format(\"IntArrayBlock(%d){positionCount=%d}\", hashCode(), getPositionCount());\n    }\n\n    private void checkReadablePosition(int position)\n    {\n        if (position < 0 || position >= getPositionCount()) {\n            throw new IllegalArgumentException(\"position is not valid\");\n        }\n    }\n\n    @Override\n    public int getOffsetBase()\n    {\n        return arrayOffset;\n    }\n\n    @Override\n    public boolean isNullUnchecked(int internalPosition)\n    {\n        assert mayHaveNull() : \"no nulls present\";\n        assert internalPositionInRange(internalPosition, getOffsetBase(), getPositionCount());\n        return valueIsNull[internalPosition];\n    }\n\n    @Override","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/IntArrayBlock.java#L224-L260","documentation":"checkReadablePosition on IntArrayBlock guards all position-based reads (getInt, isNull, writePositionTo, getSingleValueBlock, copyPositions, toLong). Positions must be in [0, getPositionCount()); anything else throws IllegalArgumentException since that position does not exist in the block.","triggerScenarios":"Calling any read API with position < 0 or position >= getPositionCount() — e.g. iterating with i <= count, reading a position from a different (larger) block, or stale indexes after slicing with arrayOffset.","commonSituations":"Off-by-one loops; cross-block position reuse after copyPositions/getRegion; operator restart code reading cached row indexes against a rebuilt page.","solutions":["Bound loops with position < block.getPositionCount().","Validate positions copied from another block against this block's count before use.","Use getRegion/copyPositions for bulk access rather than manual per-position reads across blocks."],"exampleFix":"// before\nint v = block.getInt(page.getPositionCount() - 1 + 1); // one past end\n// after\nint last = block.getPositionCount() - 1;\nif (last >= 0) { int v = block.getInt(last); }","handlingStrategy":"validation","validationCode":"if (position < 0 || position >= block.getPositionCount()) {\n    return null; // skip invalid read\n}\nint v = block.getInt(position);","typeGuard":"boolean readablePosition(Block b, int position) {\n    return position >= 0 && position < b.getPositionCount();\n}","tryCatchPattern":"try {\n    v = block.getInt(position);\n} catch (IllegalArgumentException e) {\n    throw new IllegalStateException(\"Block position \" + position + \" invalid for count \" + block.getPositionCount(), e);\n}","preventionTips":["Always bound loops by the same block instance's getPositionCount()","Do not reuse positions across different block instances","Use getRegion/copyPositions for cross-block bulk access"],"tags":["presto","block","illegal-argument","bounds-check"],"backgroundTag":"position-out-of-range","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}