videojs/video.js · error · Error
Failed to execute '${fnName}' on 'TimeRanges': The index pro
Error message
Failed to execute '${fnName}' on 'TimeRanges': The index provided (${index}) is non-numeric or out of bounds (0-${maxIndex}). What it means
Thrown by the private rangeCheck helper guarding TimeRanges start(i)/end(i). It fires when the index is non-numeric, negative, or greater than length-1. This mirrors the native HTML5 TimeRanges spec error and is bound into every non-empty TimeRanges object returned by player.buffered/seekable/played.
Source
Thrown at src/js/utils/time.js:57
/**
* Check if any of the time ranges are over the maximum index.
*
* @private
* @param {string} fnName
* The function name to use for logging
*
* @param {number} index
* The index to check
*
* @param {number} maxIndex
* The maximum possible index
*
* @throws {Error} if the timeRanges provided are over the maxIndex
*/
function rangeCheck(fnName, index, maxIndex) {
if (typeof index !== 'number' || index < 0 || index > maxIndex) {
throw new Error(`Failed to execute '${fnName}' on 'TimeRanges': The index provided (${index}) is non-numeric or out of bounds (0-${maxIndex}).`);
}
}
/**
* Get the time for the specified index at the start or end
* of a TimeRange object.
*
* @private
* @param {string} fnName
* The function name to use for logging
*
* @param {string} valueIndex
* The property that should be used to get the time. should be
* 'start' or 'end'
*
* @param {Array} ranges
* An array of time ranges
*View on GitHub (pinned to c3a7e0e6d2)
Solutions
- Check timeRanges.length before indexing.
- Iterate with for (let i = 0; i < ranges.length; i++).
- Coalesce to a safe index: const idx = Math.min(i, ranges.length - 1).
Example fix
// before const end = player.buffered().end(1); // after const b = player.buffered(); const end = b.length >= 2 ? b.end(1) : (b.length === 1 ? b.end(0) : 0);
Defensive patterns
Strategy: validation
Validate before calling
function rangeAt(ranges, fn, i = 0) {
if (typeof i !== 'number' || i < 0 || i >= ranges.length) {
throw new RangeError(`index ${i} out of bounds for length ${ranges.length}`);
}
return ranges[fn](i);
} Type guard
function isValidRangeIndex(ranges, i) {
return typeof i === 'number' && i >= 0 && i < ranges.length;
} Try / catch
try {
return ranges.start(i);
} catch (err) {
if (/TimeRanges/.test(err.message) && /out of bounds|non-numeric/.test(err.message)) {
return ranges.length ? ranges.start(ranges.length - 1) : 0;
}
throw err;
} Prevention
- Always check ranges.length before indexing start()/end().
- Loop with for (let i = 0; i < ranges.length; i++), never i <= length.
- Coerce string indices to Number and validate before passing.
When it happens
Trigger: Calling player.buffered().start(5) when fewer ranges exist; passing a string index; an off-by-one loop (i <= length instead of i < length); calling start()/end() with no index on a non-empty object (the deprecated default of 0 is tolerated).
Common situations: Looping over buffered/seekable ranges without checking .length; assuming exactly one buffered range for progressive downloads; computing progress as buffered().end(length-1) on a live/HLS stream where ranges shift.
Related errors
- This TimeRanges object is empty
- currentDimension only accepts width or height value
- Illegal component name, "${name}"; must be a non-empty strin
- Illegal component, "${name}"; ${reason}.
- Invalid target for ${objName(obj)}#${fnName}; must be a DOM
AI-assisted analysis of videojs/video.js@c3a7e0e6d2 (2026-08-13).
Data as JSON: /api/errors/f9e201911ccfe510.
Report an issue: GitHub.