{"record":{"id":"397968cc34d1deb8","repo":"prestodb/presto","slug":"positioncount-is-negative-397968","errorCode":null,"errorMessage":"positionCount is negative","messagePattern":"positionCount is negative","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"presto-common/src/main/java/com/facebook/presto/common/block/RunLengthEncodedBlock.java","lineNumber":66,"sourceCode":"    private final Block value;\n    private final int positionCount;\n\n    public RunLengthEncodedBlock(Block value, int positionCount)\n    {\n        requireNonNull(value, \"value is null\");\n        if (value.getPositionCount() != 1) {\n            throw new IllegalArgumentException(format(\"Expected value to contain a single position but has %s positions\", value.getPositionCount()));\n        }\n\n        if (value instanceof RunLengthEncodedBlock) {\n            this.value = ((RunLengthEncodedBlock) value).getValue();\n        }\n        else {\n            this.value = value;\n        }\n\n        if (positionCount < 0) {\n            throw new IllegalArgumentException(\"positionCount is negative\");\n        }\n\n        this.positionCount = positionCount;\n    }\n\n    public Block getValue()\n    {\n        return value;\n    }\n\n    @Override\n    public int getPositionCount()\n    {\n        return positionCount;\n    }\n\n    @Override\n    public long getSizeInBytes()","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/RunLengthEncodedBlock.java#L48-L84","documentation":"A RunLengthEncodedBlock's positionCount states how many times the single value repeats; a negative count is meaningless and would break downstream bounds checks, so the constructor validates it with IllegalArgumentException.","triggerScenarios":"Passing a negative integer as the second argument to new RunLengthEncodedBlock(value, positionCount), typically from an unchecked subtraction (e.g. rangeEnd - rangeStart) or an uninitialized variable.","commonSituations":"Computing retained positions during block compaction where start > end produces a negative delta; operator code computing 'remaining' positions that underflows.","solutions":["Validate positionCount >= 0 before constructing (clamp to 0 if an empty range is legal)","Fix the subtraction/loop bounds that produced the negative value","Use Math.max(0, end - start) when computing counts from ranges"],"exampleFix":"// before\nint count = end - start; // may be negative\nreturn new RunLengthEncodedBlock(value, count);\n// after\nint count = Math.max(0, end - start);\nreturn new RunLengthEncodedBlock(value, count);","handlingStrategy":"validation","validationCode":"// before constructing an RLE block\nif (positionCount < 0) {\n    positionCount = 0; // or throw with context about the computation\n}\nRunLengthEncodedBlock rle = new RunLengthEncodedBlock(value, positionCount);\n","typeGuard":null,"tryCatchPattern":"try {\n    return new RunLengthEncodedBlock(value, count);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().equals(\"positionCount is negative\")) {\n        throw new IllegalStateException(\"negative RLE count from range computation [\" + start + \", \" + end + \")\", e);\n    }\n    throw e;\n}","preventionTips":["Clamp range-derived counts with Math.max(0, end - start)","Log start/end when computing retained positions","Add assertions that count >= 0 in block-compaction code"],"tags":["presto","rle-block","argument-validation","bounds"],"backgroundTag":"negative-count-argument","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"}