TheAlgorithms/JavaScript · error · RangeError

Index is out of range max ${this.length}

Error message

Index is out of range max ${this.length}

What it means

Thrown by SinglyCircularLinkedList.insertAt(index, data) as a RangeError when the requested index is negative or strictly greater than the list's current length. This library treats insertion as valid over the closed range [0, length] (index 0 delegates to addAtFirst, index === length delegates to add), so anything outside that band is rejected rather than silently clamped.

Source

Thrown at Data-Structures/Linked-List/SinglyCircularLinkedList.js:62

  add(data) {
    if (!this.headNode) {
      return this.addAtFirst(data)
    }
    const node = new Node(data)
    // Getting the last node
    const currentNode = this.getElementAt(this.length - 1)
    currentNode.next = node
    node.next = this.headNode
    this.length++
    return this.length
  }

  // insert data at a specific position
  insertAt(index, data) {
    if (index === 0) return this.addAtFirst(data)
    if (index === this.length) return this.add(data)
    if (index < 0 || index > this.length)
      throw new RangeError(`Index is out of range max ${this.length}`)
    const node = new Node(data)
    const previousNode = this.getElementAt(index - 1)
    node.next = previousNode.next
    previousNode.next = node
    this.length++
    return this.length
  }

  // find the first index of the data
  indexOf(data) {
    let { currentNode } = this.initiateNodeAndIndex()
    // initializing currentIndex as -1
    let currentIndex = -1
    while (currentNode) {
      if (currentNode.data === data) {
        return currentIndex + 1
      }
      currentIndex++

View on GitHub (pinned to 5c39e87a9a)

Solutions

  1. Compute the index in 0-based terms and clamp to [0, list.length] before calling insertAt.
  2. Guard the call: if (index < 0 || index > list.length) handle the invalid case yourself.
  3. Re-read list.size() immediately before computing the index so it reflects any prior mutations.
  4. For append-style use, prefer add(data) (end) or addAtFirst(data) (head) which never throw on bounds.

Example fix

// before
list.insertAt(userIndex, value) // throws if userIndex is stale/negative

// after
const safeIndex = Math.max(0, Math.min(userIndex, list.length))
if (safeIndex !== userIndex) throw new RangeError(`clamped ${userIndex}`)
list.insertAt(safeIndex, value)
Defensive patterns

Strategy: validation

Validate before calling

function safeInsertAt(list, index, data) {
  if (!Number.isInteger(index) || index < 0 || index > list.length) {
    throw new RangeError(`index must be an integer in [0, ${list.length}]`)
  }
  return list.insertAt(index, data)
}

Type guard

const isValidInsertIndex = (list, i) =>
  Number.isInteger(i) && i >= 0 && i <= list.length

Try / catch

try {
  list.insertAt(index, data)
} catch (e) {
  if (e instanceof RangeError && /out of range/i.test(e.message)) {
    // handle bad index (e.g. clamp or report)
  } else throw e
}

Prevention

When it happens

Trigger: Calling list.insertAt(-1, x); calling list.insertAt(5, x) on a list whose length is 2; calling insertAt on an empty list with any index other than 0.

Common situations: Off-by-one after deletions shrink length; passing a 1-based index into a 0-based API; recomputing the insertion point from a stale size captured before a clear/remove.

Related errors


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