parallax/jsPDF · error · Error

Frame index out of range.

Error message

Frame index out of range.

What it means

Thrown by GifReader.frameInfo(frame_num) when the requested frame index is negative or >= frames.length. frameInfo is the entry point used by both decodeAndBlitFrameBGRA and decodeAndBlitFrameRGBA, so any out-of-range frame decode hits this. It is a standard bounds guard for an animated GIF's frame table.

Source

Thrown at src/libs/omggif.js:606

        break;

      default:
        throw new Error("Unknown gif block: 0x" + buf[p - 1].toString(16));
        break;
    }
  }

  this.numFrames = function() {
    return frames.length;
  };

  this.loopCount = function() {
    return loop_count;
  };

  this.frameInfo = function(frame_num) {
    if (frame_num < 0 || frame_num >= frames.length)
      throw new Error("Frame index out of range.");
    return frames[frame_num];
  };

  this.decodeAndBlitFrameBGRA = function(frame_num, pixels) {
    var frame = this.frameInfo(frame_num);
    var num_pixels = frame.width * frame.height;

    if (num_pixels > 512 * 1024 * 1024) {
      throw new Error("Image dimensions exceed 512MB, which is too large.");
    }

    var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices.
    GifReaderLZWOutputIndexStream(
      buf,
      frame.data_offset,
      index_stream,
      num_pixels
    );

View on GitHub (pinned to a3930ce03a)

Solutions

  1. Bounds-check against reader.numFrames() before decoding: require 0 <= frame_num < reader.numFrames().
  2. Use strict less-than in loops over frames.
  3. If the caller exposes a frame picker, clamp or reject out-of-range input before calling the decoder.

Example fix

// before
for (var i = 0; i <= reader.numFrames(); i++) {
  reader.decodeAndBlitFrameRGBA(i, pixels);
}

// after
for (var i = 0; i < reader.numFrames(); i++) {
  reader.decodeAndBlitFrameRGBA(i, pixels);
}
Defensive patterns

Strategy: validation

Validate before calling

var n = reader.numFrames();
if (!(frameNum >= 0 && frameNum < n)) {
  throw new Error('frameNum ' + frameNum + ' out of range [0,' + n + ')');
}
reader.decodeAndBlitFrameRGBA(frameNum, pixels);

Type guard

function isValidFrameIndex(reader, i) {
  return Number.isInteger(i) && i >= 0 && i < reader.numFrames();
}

Try / catch

try {
  reader.frameInfo(frameNum);
} catch (e) {
  if (/Frame index out of range/.test(e.message)) {
    return null; // clamp or skip
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling reader.decodeAndBlitFrameRGBA(n, pixels) / reader.frameInfo(n) where n is beyond the last frame, negative, or a non-integer. Commonly n equals the frame count (off-by-one) or is hardcoded to a frame index that a single-frame GIF does not have.

Common situations: Decoding an animated GIF and looping `i <= reader.numFrames()` instead of `<`; passing a user-supplied frame number without clamping; jsPDF's processGIF89A hardcodes frame 0 so this only bites custom GifReader usage.

Related errors


AI-assisted analysis of parallax/jsPDF@a3930ce03a (2026-08-13). Data as JSON: /api/errors/036db0986b0017c7. Report an issue: GitHub.