mozilla/pdf.js · error · FormatError
Reading gray scale from a color image: ${numComps}
Error message
Reading gray scale from a color image: ${numComps} What it means
Thrown by PDFImage.fillGrayBuffer when the image has more than one color component (numComps !== 1). fillGrayBuffer is meant to extract a grayscale channel; calling it on an RGB/CMYK image is a logic error because there is no single gray channel to copy.
Source
Thrown at src/core/image.js:1019
buffer,
{
destWidth,
destHeight,
invertOutput,
maxRows,
offset = 0,
stride = 1,
} = {}
) {
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
assert(
buffer instanceof Uint8ClampedArray,
'PDFImage.fillGrayBuffer: Unsupported "buffer" type.'
);
}
const numComps = this.numComps;
if (numComps !== 1) {
throw new FormatError(
`Reading gray scale from a color image: ${numComps}`
);
}
const srcWidth = this.width;
const srcHeight = this.height;
const bpc = this.bpc;
// rows start at byte boundary
const rowBytes = (srcWidth * numComps * bpc + 7) >> 3;
const imgArray = await this.getImageBytes(srcHeight * rowBytes, {
internal: true,
});
const comps = this.getComponents(imgArray);
const resolvedDestWidth = destWidth ?? srcWidth;
const resolvedDestHeight = destHeight ?? srcHeight;
const needsResampling =View on GitHub (pinned to 5903d58d58)
Solutions
- Report the PDF to pdf.js maintainers; this is normally an internal dispatch mismatch.
- Ensure the source PDF's /SMask and /Mask reference single-channel (gray) images as the spec requires.
- Catch FormatError and fall back to full RGBA compositing without the gray fast-path.
- Regenerate the PDF so soft masks use 1-component images.
Defensive patterns
Strategy: validation
Validate before calling
// Before calling fillGrayBuffer, ensure the image is single-channel:
function canFillGray(image) {
return image?.numComps === 1;
} Type guard
function isSingleComponentImage(image) {
return image != null && image.numComps === 1;
} Try / catch
try { await page.render({ canvasContext }).promise; }
catch (err) {
if (/Reading gray scale from a color image/.test(err?.message || '')) {
console.warn('Gray fill requested on multi-component image; skipping.');
} else throw err;
} Prevention
- Author /SMask and /Mask as single-channel images per the PDF spec.
- Do not call fillGrayBuffer on RGB/CMYK images if you use pdf.js internals directly.
- Report dispatcher bugs upstream with the reproducing PDF.
When it happens
Trigger: fillGrayBuffer is invoked on a multi-component image, typically as a sub-step of compositing a single-channel mask or smask whose underlying image was mistakenly treated as gray. Reached during alpha/mask fill operations.
Common situations: Usually an internal dispatch bug (a mask image resolved to a multi-component PDFImage) rather than a user config issue; can be triggered by PDFs whose SMask/Mask references point at a color image instead of a gray one.
Related errors
- Unknown mask format.
- Image exceeded maximum allowed size and was removed.
- Unable to decode inline image: "${reason}".
- Invalid image width: ${width} or height: ${height}
- Bits per component missing in image: ${this.imageMask}
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/aab92b2e3daa62a1.
Report an issue: GitHub.