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
- Bounds-check against reader.numFrames() before decoding: require 0 <= frame_num < reader.numFrames().
- Use strict less-than in loops over frames.
- 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
- Always loop frames with `i < reader.numFrames()` (strict less-than).
- Clamp user-supplied frame numbers into [0, numFrames-1].
- Default to frame 0 when the requested frame is unavailable.
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
- Image dimensions exceed 512MB, which is too large.
- Width/Height invalid.
- Invalid code/color length, must be power of 2 and 2 .. 256.
- Background index out of range.
- Background index explicitly passed as 0.
AI-assisted analysis of parallax/jsPDF@a3930ce03a (2026-08-13).
Data as JSON: /api/errors/036db0986b0017c7.
Report an issue: GitHub.