{"record":{"id":"0b08da2379b857ab","repo":"prestodb/presto","slug":"positioncount-is-negative-0b08da","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/ByteArrayBlock.java","lineNumber":70,"sourceCode":"    @Nullable\n    private final boolean[] valueIsNull;\n    private final byte[] values;\n\n    private final long retainedSizeInBytes;\n\n    public ByteArrayBlock(int positionCount, Optional<boolean[]> valueIsNull, byte[] values)\n    {\n        this(0, positionCount, valueIsNull.orElse(null), values);\n    }\n\n    ByteArrayBlock(int arrayOffset, int positionCount, boolean[] valueIsNull, byte[] values)\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 (values.length - arrayOffset < positionCount) {\n            throw new IllegalArgumentException(\"values length is less than positionCount\");\n        }\n        this.values = values;\n\n        if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {\n            throw new IllegalArgumentException(\"isNull length is less than positionCount\");\n        }\n        this.valueIsNull = valueIsNull;\n\n        retainedSizeInBytes = (INSTANCE_SIZE + sizeOf(valueIsNull) + sizeOf(values));\n    }\n\n    @Override\n    public long getSizeInBytes()","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/ByteArrayBlock.java#L52-L88","documentation":"The ByteArrayBlock constructor rejects a negative positionCount (the number of logical positions in the block). A negative count is meaningless for a block and would corrupt downstream iteration and length checks, so the constructor throws this IllegalArgumentException as a precondition guard.","triggerScenarios":"Constructing ByteArrayBlock with positionCount < 0, typically from a computed count such as end - start where start > end, or from subtraction underflow when deriving position counts from offsets.","commonSituations":"Slicing code where the range bounds were swapped (from > to); overflow in int arithmetic producing a negative count; connector code passing a result-size variable that was initialized to -1 as a sentinel and never replaced.","solutions":["Fix the count computation so it is non-negative; check for swapped range bounds (ensure end >= start before computing end - start).","Replace -1 sentinel values with 0 or Optional before constructing the block.","For an empty block, pass positionCount 0 rather than a negative or sentinel value."],"exampleFix":"// before\nint count = endIndex - startIndex; // startIndex > endIndex -> negative\nnew ByteArrayBlock(0, count, valueIsNull, values);\n// after\nint count = Math.max(0, endIndex - startIndex);\ncheckState(endIndex >= startIndex, \"invalid range: start=%s end=%s\", startIndex, endIndex);\nnew ByteArrayBlock(0, count, valueIsNull, values);","handlingStrategy":"validation","validationCode":"if (positionCount < 0) {\n    throw new IllegalArgumentException(\"computed positionCount is negative: \" + positionCount);\n}\nnew ByteArrayBlock(arrayOffset, positionCount, valueIsNull, values);","typeGuard":"boolean isValidPositionCount(int positionCount) {\n    return positionCount >= 0;\n}","tryCatchPattern":"try {\n    block = new ByteArrayBlock(arrayOffset, positionCount, valueIsNull, values);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().equals(\"positionCount is negative\")) {\n        throw new IllegalStateException(\"negative position count from range [\" + start + \", \" + end + \")\", e);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Check range bounds (end >= start) before computing count = end - start.","Replace -1 sentinel result sizes with 0 or Optional before constructing blocks.","Use Math.max(0, end - start) only when an empty result is the intended semantics.","Watch for int overflow in count arithmetic; use long intermediates for large ranges."],"tags":["presto","block","argument-validation","bytearray"],"backgroundTag":"invalid-argument","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"}