{"record":{"id":"f40d2d26b63c78bf","repo":"prestodb/presto","slug":"position-is-not-valid-f40d2d","errorCode":null,"errorMessage":"position is not valid","messagePattern":"position is not valid","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/block/AbstractRowBlock.java","lineNumber":382,"sourceCode":"\n        Block[] rawFieldBlocks = getRawFieldBlocks();\n        long size = 0;\n        for (int i = 0; i < numFields; i++) {\n            size += rawFieldBlocks[i].getEstimatedDataSizeForStats(getFieldBlockOffset(position));\n        }\n        return size;\n    }\n\n    @Override\n    public boolean mayHaveNull()\n    {\n        return getRowIsNull() != null;\n    }\n\n    protected final 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 Block getBlockUnchecked(int internalPosition)\n    {\n        assert internalPositionInRange(internalPosition, getOffsetBase(), getPositionCount());\n        return new SingleRowBlock(getFieldBlockOffsets()[internalPosition], getRawFieldBlocks());\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 getRowIsNull()[internalPosition];\n    }\n","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/AbstractRowBlock.java#L364-L400","documentation":"AbstractRowBlock.checkReadablePosition validates that a position argument is within [0, positionCount). Any reader API (copyPositions, getBlock, writePositionTo, getSingleValueBlock, getEstimatedDataSizeForStats) called with an out-of-range position throws IllegalArgumentException with the generic message \"position is not valid\".","triggerScenarios":"Calling any of those public reader methods with a negative position, or a position >= the block's position count; commonly from iterating past the end or using positions from a different block.","commonSituations":"Off-by-one loops in custom operators/expression implementations; using an internal position where an external one is expected; null-handling bugs that skip a position decrement.","solutions":["Clamp/bound loop indices with block.getPositionCount() before calling reader methods.","Verify the position source: only pass positions produced for this same block, not stale or foreign indices.","Use block iterator or getPositions/processing APIs that enforce bounds automatically.","Reproduce with the caller stack trace and fix the off-by-one in the operator rather than catching the exception."],"exampleFix":"// before\nfor (int i = 0; i <= block.getPositionCount(); i++) {\n    block.writePositionTo(i, output);\n}\n// after\nfor (int i = 0; i < block.getPositionCount(); i++) {\n    block.writePositionTo(i, output);\n}","handlingStrategy":"type-guard","validationCode":"static boolean isValidPosition(Block block, int position) {\n    return position >= 0 && position < block.getPositionCount();\n}","typeGuard":"static boolean hasReadablePosition(Block block, int position) {\n    return block != null && position >= 0 && position < block.getPositionCount();\n}","tryCatchPattern":"try {\n    block.writePositionTo(position, output);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().equals(\"position is not valid\")) {\n        throw new IndexOutOfBoundsException(\"position \" + position + \" out of range for block of \" + block.getPositionCount());\n    }\n    throw e;\n}","preventionTips":["Always bound loops with block.getPositionCount() using strict '<'.","Track position provenance: only pass positions generated for the same block.","Prefer Block.getChildren/getBlock slices over manual position arithmetic."],"tags":["presto","block","row-block","bounds-check","illegal-argument"],"backgroundTag":"position-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"}