{"record":{"id":"dc355a7391103753","repo":"quarkusio/quarkus","slug":"last-index-must-be-start-index-is-not-larger","errorCode":null,"errorMessage":"Last index must be >= start index:  is not larger or equal to ","messagePattern":"Last index must be >= start index:  is not larger or equal to ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/panache/panache-common/runtime/src/main/java/io/quarkus/panache/common/Range.java","lineNumber":35,"sourceCode":" */\npublic class Range {\n    // FIXME: bump to long? Jakarta Data uses longs for its Limit type\n    private final int startIndex;\n    private final int lastIndex;\n\n    /**\n     * Creates a new range\n     *\n     * @param startIndex the start index to include, 0-based\n     * @param lastIndex the end index to include, 0-based\n     */\n    public Range(int startIndex, int lastIndex) {\n        if (startIndex < 0)\n            throw new IllegalArgumentException(\"Start index must be >= 0: \" + startIndex);\n        if (lastIndex < 0)\n            throw new IllegalArgumentException(\"Last index must be >= 0: \" + lastIndex);\n        if (lastIndex < startIndex)\n            throw new IllegalArgumentException(\n                    \"Last index must be >= start index: \" + lastIndex + \" is not larger or equal to \" + startIndex);\n        this.startIndex = startIndex;\n        this.lastIndex = lastIndex;\n    }\n\n    /**\n     * Creates a new range\n     *\n     * @param startIndex the start index to include, 0-based\n     * @param lastIndex the end index to include, 0-based\n     */\n    public static Range of(int startIndex, int lastIndex) {\n        return new Range(startIndex, lastIndex);\n    }\n\n    /**\n     * @return the start index to include, 0-based\n     */","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/panache/panache-common/runtime/src/main/java/io/quarkus/panache/common/Range.java#L17-L53","documentation":"Range requires lastIndex >= startIndex because an inclusive 0-based range whose end precedes its start is invalid. The constructor throws IllegalArgumentException embedding both offending values in the message.","triggerScenarios":"Calling new Range(5, 2) or Range.of where the computed end is smaller than the start — commonly from reversed offsets, swapped arguments, or negative-count math.","commonSituations":"Argument order confusion (passing end, start instead of start, end); slicing with start beyond the data length; count math yielding end < start after clamping only one bound.","solutions":["Validate before constructing: if (last < start) swap them or return an empty result.","Clamp both ends: start=Math.max(0,start); end=Math.max(start,end).","Check argument order at call sites of Range.of."],"exampleFix":"// before\nRange r = Range.of(start, end); // end may be < start\n// after\nint s = Math.max(0, start);\nRange r = Range.of(s, Math.max(s, end));","handlingStrategy":"validation","validationCode":"if (lastIndex < startIndex) {\n    throw new BadRequestException(\"lastIndex must be >= startIndex\");\n}\nRange r = Range.of(startIndex, lastIndex);","typeGuard":"Range orderedRange(int a, int b) {\n    int start = Math.max(0, Math.min(a, b));\n    int last  = Math.max(start, Math.max(a, b));\n    return Range.of(start, last);\n}","tryCatchPattern":"try {\n    Range r = Range.of(startIndex, lastIndex);\n} catch (IllegalArgumentException e) {\n    throw new BadRequestException(\"Invalid range: \" + e.getMessage());\n}","preventionTips":["Verify argument order in Range.of(start, last) call sites","Normalize/swap bounds before constructing","Clamp both bounds consistently"],"tags":["panache","range","pagination","illegal-argument"],"backgroundTag":"invalid-range-bounds","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}