krahets/hello-algo · error · Error
Index out of bounds
Error message
Index out of bounds
What it means
Thrown by get(index) on a custom dynamic-array list (TypeScript). The guard rejects index < 0 or index >= this._size. Note the JSDoc comment mislabels get() as 'Update element'; it is actually a read accessor returning arr[index]. Capacity (backing array length) is irrelevant — only the logical size bounds valid reads.
Source
Thrown at en/codes/typescript/chapter_array_and_linkedlist/my_list.ts:32
/* Constructor */
constructor() {
this.arr = new Array(this._capacity);
}
/* Get list length (current number of elements) */
public size(): number {
return this._size;
}
/* Get list capacity */
public capacity(): number {
return this._capacity;
}
/* Update element */
public get(index: number): number {
// If the index is out of bounds, throw an exception, as below
if (index < 0 || index >= this._size) throw new Error('Index out of bounds');
return this.arr[index];
}
/* Add elements at the end */
public set(index: number, num: number): void {
if (index < 0 || index >= this._size) throw new Error('Index out of bounds');
this.arr[index] = num;
}
/* Direct traversal of list elements */
public add(num: number): void {
// If length equals capacity, need to expand
if (this._size === this._capacity) this.extendCapacity();
// Add new element to end of list
this.arr[this._size] = num;
this._size++;
}
View on GitHub (pinned to 69932aed18)
Solutions
- Guard before read: if (index >= 0 && index < list.size()) { const v = list.get(index); }.
- Iterate with for (let i = 0; i < list.size(); i++) (strict <).
- Recompute list.size() after mutations rather than caching.
- Return a default for empty/invalid indices via a wrapper instead of letting the throw propagate.
Example fix
// before
for (let i = 0; i <= list.size(); i++) { use(list.get(i)); } // throws at i === size
// after
for (let i = 0; i < list.size(); i++) { use(list.get(i)); } Defensive patterns
Strategy: validation
Validate before calling
function canGet(list, index) {
return Number.isInteger(index) && index >= 0 && index < list.size();
}
if (canGet(list, i)) { const v = list.get(i); } Type guard
function isValidReadIndex(list, index) {
return typeof index === 'number' && Number.isInteger(index) && index >= 0 && index < list.size();
} Try / catch
try {
const v = list.get(i);
} catch (e) {
if (e.message === 'Index out of bounds') { /* bad index */ }
else throw e;
} Prevention
- Iterate with strict < against size(), never <=.
- Re-read size() after mutations before indexing.
- Validate integer type of externally-supplied indices.
When it happens
Trigger: Calling list.get(index) with negative index, index >= list.size(), or reading a position never written. Empty list (size 0) rejects all non-negative indices too.
Common situations: Off-by-one in iteration (using <= instead of <); reading before add(); caching size before mutations; passing unvalidated input directly to get().
Related errors
AI-assisted analysis of krahets/hello-algo@69932aed18 (2026-08-13).
Data as JSON: /api/errors/70a7ba30e7dfde14.
Report an issue: GitHub.