videojs/video.js · error · Error

This TimeRanges object is empty

Error message

This TimeRanges object is empty

What it means

Thrown by the start() method on a TimeRanges object created empty (ranges undefined or length 0). createTimeRangesObj installs start/end stubs that throw immediately to signal there is no range data, rather than returning undefined. Represents a player state with no buffered/seekable/played data.

Source

Thrown at src/js/utils/time.js:106

}

/**
 * Create a time range object given ranges of time.
 *
 * @private
 * @param   {Array} [ranges]
 *          An array of time ranges.
 *
 * @return  {TimeRange}
 */
function createTimeRangesObj(ranges) {
  let timeRangesObj;

  if (ranges === undefined || ranges.length === 0) {
    timeRangesObj = {
      length: 0,
      start() {
        throw new Error('This TimeRanges object is empty');
      },
      end() {
        throw new Error('This TimeRanges object is empty');
      }
    };
  } else {
    timeRangesObj = {
      length: ranges.length,
      start: getRange.bind(null, 'start', 0, ranges),
      end: getRange.bind(null, 'end', 1, ranges)
    };
  }

  if (window.Symbol && window.Symbol.iterator) {
    timeRangesObj[window.Symbol.iterator] = () => (ranges || []).values();
  }

  return timeRangesObj;

View on GitHub (pinned to c3a7e0e6d2)

Solutions

  1. Guard with if (ranges.length > 0) before calling start()/end().
  2. Wait for 'progress' or 'loadedmetadata' events before reading buffered/seekable.
  3. Coalesce to 0: const s = buf.length ? buf.start(buf.length - 1) : 0.

Example fix

// before
const start = player.buffered().start(0);
// after
const b = player.buffered();
const start = b.length ? b.start(0) : 0;
Defensive patterns

Strategy: validation

Validate before calling

function safeStart(ranges) {
  return ranges.length ? ranges.start(0) : 0;
}

Type guard

function hasRanges(ranges) {
  return ranges && ranges.length > 0;
}

Try / catch

try {
  return ranges.start(0);
} catch (err) {
  if (/TimeRanges object is empty/.test(err.message)) return 0;
  throw err;
}

Prevention

When it happens

Trigger: Calling player.buffered().start(0) before any media data has buffered; reading start() immediately after a source change or a flush that clears ranges; on live streams before a seekable window is established.

Common situations: Reading buffered progress at 'ready' or synchronously after src() before 'loadedmetadata'/'progress' fire; HLS/DASH streams with no buffered ranges yet; calling end() to draw a progress bar before playback begins.

Related errors


AI-assisted analysis of videojs/video.js@c3a7e0e6d2 (2026-08-13). Data as JSON: /api/errors/bd6d3ed04181373a. Report an issue: GitHub.