{"record":{"id":"31eacb007c4c64f7","repo":"prestodb/presto","slug":"positioncount-is-negative-31eacb","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/ShortArrayBlock.java","lineNumber":61,"sourceCode":"    @Nullable\n    private final boolean[] valueIsNull;\n    private final short[] values;\n\n    private final long retainedSizeInBytes;\n\n    public ShortArrayBlock(int positionCount, Optional<boolean[]> valueIsNull, short[] values)\n    {\n        this(0, positionCount, valueIsNull.orElse(null), values);\n    }\n\n    ShortArrayBlock(int arrayOffset, int positionCount, boolean[] valueIsNull, short[] 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":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-common/src/main/java/com/facebook/presto/common/block/ShortArrayBlock.java#L43-L79","documentation":"ShortArrayBlock's constructor validates its arguments before storing them. positionCount represents the number of entries in the block, and a negative count is meaningless, so the constructor throws IllegalArgumentException immediately rather than creating a corrupt block. This is a fail-fast guard against bad block construction.","triggerScenarios":"Calling ShortArrayBlock's constructor (directly or via factory methods like ShortArrayBlock.fromShortArray) with a negative positionCount argument.","commonSituations":"Custom block building code that computes positionCount via subtraction (e.g. end - start on swapped indices), off-by-one bugs in aggregation/partitioning code, or deserialization feeding a corrupted/underflowed int.","solutions":["Check the caller's positionCount computation for swapped or underflowing arithmetic (e.g. end - start with end < start).","Clamp or validate the value before constructing: if (positionCount < 0) throw ... or use Math.max(0, positionCount).","Verify the data source (e.g. deserialized length field) is not corrupted; re-serialize the input."],"exampleFix":"// before\nint count = end - start;\nBlock block = new ShortArrayBlock(0, count, new short[8], null);\n// after\nint count = Math.max(0, end - start);\ncheckArgument(end >= start, \"end before start\");\nBlock block = new ShortArrayBlock(0, count, new short[8], null);","handlingStrategy":"validation","validationCode":"if (positionCount < 0) {\n    throw new IllegalArgumentException(\"positionCount must be >= 0, got \" + positionCount);\n}","typeGuard":"boolean isValidBlockShape(int arrayOffset, int positionCount, short[] values) {\n    return arrayOffset >= 0 && positionCount >= 0 && values.length - arrayOffset >= positionCount;\n}","tryCatchPattern":"try {\n    Block block = new ShortArrayBlock(arrayOffset, positionCount, values, valueIsNull);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"positionCount is negative\")) {\n        positionCount = Math.max(0, positionCount); // or log and rethrow with context\n    } else {\n        throw e;\n    }\n}","preventionTips":["Compute positionCount as end - start and assert end >= start before constructing.","Use Math.max(0, n) when deriving counts from possibly-underflowing arithmetic.","Unit-test block construction with boundary values (0, -1, Integer.MAX_VALUE)."],"tags":["presto","block","illegal-argument","arrayblock"],"backgroundTag":"negative-count-illegal-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"}