trekhleb/javascript-algorithms · error · Error
Left index can not be greater than right one
Error message
Left index can not be greater than right one
What it means
FenwickTree.queryRange(leftIndex, rightIndex) returns the inclusive sum over [leftIndex, rightIndex] as query(rightIndex) - query(leftIndex - 1), and it first rejects leftIndex > rightIndex with this error because a reversed pair would produce a nonsense negative-range result. Both bounds are ultimately fed to query(), so they must also respect the tree's 1-based domain 1..arraySize. The error is pure argument-order validation, not a state problem.
Source
Thrown at src/data-structures/tree/fenwick-tree/FenwickTree.js:63
let sum = 0;
for (let i = position; i > 0; i -= (i & -i)) {
sum += this.treeArray[i];
}
return sum;
}
/**
* Query sum from index leftIndex to rightIndex.
*
* @param {number} leftIndex
* @param {number} rightIndex
* @return {number}
*/
queryRange(leftIndex, rightIndex) {
if (leftIndex > rightIndex) {
throw new Error('Left index can not be greater than right one');
}
if (leftIndex === 1) {
return this.query(rightIndex);
}
return this.query(rightIndex) - this.query(leftIndex - 1);
}
}
View on GitHub (pinned to 85293e3e2b)
Solutions
- Normalize the pair before calling: queryRange(Math.min(a, b), Math.max(a, b)).
- If your convention is half-open [from, to), translate: queryRange(from + 1, to) with 1-based bounds — and return 0 for empty ranges instead of letting bounds cross.
- Validate both bounds against the tree domain: leftIndex >= 1 && rightIndex <= tree.arraySize && leftIndex <= rightIndex.
Example fix
// before
function rangeSum(a, b) {
return ft.queryRange(a, b); // throws when a > b
}
// after
function rangeSum(a, b) {
const [left, right] = a <= b ? [a, b] : [b, a];
return ft.queryRange(left, right);
} Defensive patterns
Strategy: validation
Validate before calling
function safeRangeSum(tree, leftIndex, rightIndex) {
const left = Math.min(leftIndex, rightIndex);
const right = Math.max(leftIndex, rightIndex);
if (left < 1 || right > tree.arraySize) {
throw new RangeError(`range must be inside [1, ${tree.arraySize}]`);
}
return tree.queryRange(left, right);
} Prevention
- Normalize user-supplied ranges once, at the API boundary: order the endpoints, clamp to [1, arraySize], and return 0 for empty ranges.
- Write down each function's range convention (this tree is inclusive [left, right]) next to the call site.
- Unit-test degenerate ranges: single element (l === r), full range, and reversed inputs.
- Prefer queryRange(l, r) over hand-rolled query(r) - query(l - 1) so the order guard always applies.
When it happens
Trigger: Swapping the two arguments, e.g. queryRange(right, left); treating the range as [exclusive, inclusive] and passing rightIndex = leftIndex - 1 for what should be an empty range; clamping bounds with Math.max and Math.min in the wrong order so a degenerate range arrives reversed.
Common situations: Adapting a caller whose range convention is [start, end) to this tree's inclusive [start, end]; user-supplied range inputs (date windows, slice bounds) not normalized before the call; refactors that rename left/right parameters and swap their call sites.
Related errors
- Position is out of allowed range
- You have to implement heap pair comparison method
- Item not found in the tree
- Can't remove ${value}. Remove method is not implemented yet
AI-assisted analysis of trekhleb/javascript-algorithms@85293e3e2b (2026-08-24).
Data as JSON: /api/errors/53e4a6b662d3cf94.
Report an issue: GitHub.