TheAlgorithms/JavaScript · error · RangeError

Index Out of Bound

Error message

Index Out of Bound

What it means

Thrown by QuickSelect when kth is less than 1 or greater than items.length. kth is a 1-based ordinal (the kth smallest element), not a 0-based index, so valid values are 1..items.length. It is a RangeError because the index is out of the valid range, distinct from a TypeError.

Source

Thrown at Data-Structures/Array/QuickSelect.js:16

/**
 * [QuickSelect](https://www.geeksforgeeks.org/quickselect-algorithm/) is an algorithm to find the kth smallest number
 *
 * Notes:
 * -QuickSelect is related to QuickSort, thus has optimal best and average
 * -case (O(n)) but unlikely poor worst case (O(n^2))
 * -This implementation uses randomly selected pivots for better performance
 *
 * @complexity: O(n) (on average )
 * @complexity: O(n^2) (worst case)
 * @flow
 */

function QuickSelect(items, kth) {
  if (kth < 1 || kth > items.length) {
    throw new RangeError('Index Out of Bound')
  }

  return RandomizedSelect(items, 0, items.length - 1, kth)
}

function RandomizedSelect(items, left, right, i) {
  if (left === right) return items[left]

  const pivotIndex = RandomizedPartition(items, left, right)
  const k = pivotIndex - left + 1

  if (i === k) return items[pivotIndex]
  if (i < k) return RandomizedSelect(items, left, pivotIndex - 1, i)

  return RandomizedSelect(items, pivotIndex + 1, right, i - k)
}

function RandomizedPartition(items, left, right) {

View on GitHub (pinned to 5c39e87a9a)

Solutions

  1. Remember kth is 1-based: for the smallest element pass 1, for the largest pass items.length.
  2. Guard the empty-array case before calling: if (items.length === 0) return undefined.
  3. Clamp kth: Math.max(1, Math.min(items.length, kth)).

Example fix

// before
QuickSelect(items, 0) // wanted smallest
// after
QuickSelect(items, 1) // 1-based: smallest element
Defensive patterns

Strategy: validation

Validate before calling

if (!Array.isArray(items) || items.length === 0) {
  throw new Error('items must be a non-empty array')
}
if (!Number.isInteger(kth) || kth < 1 || kth > items.length) {
  throw new RangeError(`kth must be an integer in 1..${items.length}`)
}
QuickSelect(items, kth)

Type guard

const isValidKth = (items, kth) =>
  Array.isArray(items) && items.length > 0 &&
  Number.isInteger(kth) && kth >= 1 && kth <= items.length

Try / catch

try {
  QuickSelect(items, kth)
} catch (e) {
  if (e instanceof RangeError && /Index Out of Bound/.test(e.message)) {
    return QuickSelect(items, Math.max(1, Math.min(items.length, kth)))
  }
  throw e
}

Prevention

When it happens

Trigger: Calling QuickSelect(arr, 0) (kth must be >= 1), QuickSelect(arr, arr.length + 1), QuickSelect([], 1) (empty array means length 0, so any kth > 0 fails), or QuickSelect(arr, -1).

Common situations: Treating kth as a 0-based array index (passing 0 for the first element); forgetting to handle the empty-array case; off-by-one when computing kth as items.length (that is the max, valid) vs items.length + 1 (invalid); passing a percentile-derived k without clamping.

Related errors


AI-assisted analysis of TheAlgorithms/JavaScript@5c39e87a9a (2026-08-13). Data as JSON: /api/errors/975ff3aa388c8c18. Report an issue: GitHub.