{"record":{"id":"5fe7e13acb676bf1","repo":"mozilla/pdf.js","slug":"unsupported-number-of-components-numcomps","errorCode":null,"errorMessage":"Unsupported number of components: ${numComps}","messagePattern":"Unsupported number of components: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/icc_colorspace.js","lineNumber":89,"sourceCode":"            this.#transformer,\n            src[srcOffset] * 255,\n            src[srcOffset + 1] * 255,\n            src[srcOffset + 2] * 255\n          );\n        break;\n      case 4:\n        inType = DataType.CMYK;\n        this.#convertPixel = (src, srcOffset) =>\n          qcms_convert_four(\n            this.#transformer,\n            src[srcOffset] * 255,\n            src[srcOffset + 1] * 255,\n            src[srcOffset + 2] * 255,\n            src[srcOffset + 3] * 255\n          );\n        break;\n      default:\n        throw new Error(`Unsupported number of components: ${numComps}`);\n    }\n    this.#transformer = qcms_transformer_from_memory(\n      iccProfile,\n      inType,\n      Intent.Perceptual\n    );\n    if (!this.#transformer) {\n      throw new Error(\"Failed to create ICC color space\");\n    }\n    IccColorSpace.#finalizer ||= new FinalizationRegistry(transformer => {\n      qcms_drop_transformer(transformer);\n    });\n    IccColorSpace.#finalizer.register(this, this.#transformer);\n  }\n\n  getRgbHex(src, srcOffset) {\n    const color = this.#convertPixel(src, srcOffset);\n    return Util.makeHexColor(color >> 16, (color >> 8) & 0xff, color & 0xff);","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/mozilla/pdf.js/blob/5903d58d58e4dd9ce6ffa3834aea8480f06b4ada/src/core/icc_colorspace.js#L71-L107","documentation":"Thrown by the IccColorSpace constructor when numComps (number of color components) is not 1 (Gray), 3 (RGB), or 4 (CMYK). QCMS only knows how to transform these four input data types; any other component count has no corresponding DataType and is rejected before a transformer is created.","triggerScenarios":"An ICCBased color space dictionary whose N (number of components) is a value like 2, 5, or 6 is parsed. Reached when rendering a PDF whose ICC profile declares an unusual channel count (e.g. multi-channel or Lab-derived ICC profiles).","commonSituations":"Specialized ICC profiles (Lab, multi-channel, device-link with >4 channels) embedded in PDFs; corrupt N values from a damaged dict; PDFs generated by color-management tools that emit non-standard component counts.","solutions":["Pre-convert the source PDF's images to a standard Gray/RGB/CMYK ICC profile before rendering.","If you control the PDF, ensure ICCBased color spaces declare N as 1, 3, or 4.","Catch the error and fall back to a non-ICC rendering path (disable useWasm/useWorkerFetch to skip ICC).","Report the file to pdf.js if a standard profile triggers it."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate ICC color space component counts you embed/parse.\nfunction isSupportedIccComponentCount(n) {\n  return n === 1 || n === 3 || n === 4;\n}","typeGuard":"function isQcmsSupportedComponents(numComps) {\n  return numComps === 1 || numComps === 3 || numComps === 4;\n}","tryCatchPattern":"try { await page.render({ canvasContext }).promise; }\ncatch (err) {\n  if (/Unsupported number of components/.test(err?.message || '')) {\n    console.warn('ICC profile has unsupported channel count; skipping image.');\n  } else throw err;\n}","preventionTips":["Restrict embedded ICC profiles to Gray/RGB/CMYK variants.","Pre-convert source images to standard channel counts before PDF embedding.","Catch the error to degrade rather than aborting the whole render."],"tags":["pdf","icc","color-space","qcms","malformed-pdf"],"backgroundTag":null,"analyzedSha":"5903d58d58e4dd9ce6ffa3834aea8480f06b4ada","analyzedAt":"2026-08-13T02:28:27.364Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}