{"record":{"id":"03fef120c470c542","repo":"gchq/CyberChef","slug":"error-loading-image-err-03fef1","errorCode":null,"errorMessage":"Error loading image. (${err})","messagePattern":"Error loading image\\. \\((.+?)\\)","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/ImageHueSaturationLightness.mjs","lineNumber":73,"sourceCode":"    }\n\n    /**\n     * @param {ArrayBuffer} input\n     * @param {Object[]} args\n     * @returns {byteArray}\n     */\n    async run(input, args) {\n        const [hue, saturation, lightness] = args;\n\n        if (!isImage(input)) {\n            throw new OperationError(\"Invalid file type.\");\n        }\n\n        let image;\n        try {\n            image = await Jimp.read(input);\n        } catch (err) {\n            throw new OperationError(`Error loading image. (${err})`);\n        }\n        try {\n            if (hue !== 0) {\n                if (isWorkerEnvironment())\n                    self.sendStatusMessage(\"Changing image hue...\");\n                image.color([\n                    {\n                        apply: \"hue\",\n                        params: [hue],\n                    },\n                ]);\n            }\n            if (saturation !== 0) {\n                if (isWorkerEnvironment())\n                    self.sendStatusMessage(\"Changing image saturation...\");\n                image.color([\n                    {\n                        apply: \"saturate\",","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/ImageHueSaturationLightness.mjs#L55-L91","documentation":"Wraps any failure of Jimp.read(input). The magic bytes passed isImage, but Jimp could not decode the body (truncated, corrupt, or an unsupported subtype/version). The original error string is interpolated so you can see Jimp's reason. It is an OperationError treated as expected step output.","triggerScenarios":"isImage returned a mime (signature present) but Jimp rejects the payload: a half-downloaded image, a header with bad CRC, a GIF/PNG with an unsupported chunk, or a format Jimp's bundled codecs cannot decode (e.g. some TIFF/ICO). Reading an ArrayBuffer whose content length is shorter than the header implies also triggers it.","commonSituations":"Truncated copy-paste of image bytes, an image that opens in a browser but uses a codec Jimp lacks, jimp version skew (a codec was dropped), or feeding an ArrayBuffer that is a valid signature wrapped around unrelated data.","solutions":["Inspect ${err}: a Jimp 'Unsupported MIME' or 'Premature end' message tells you exactly what is wrong.","Re-export or re-save the source image as PNG or JPEG and retry.","Verify the buffer length matches the declared image size (no truncation).","Check the installed jimp version supports the input codec."],"exampleFix":"// before\nconst buf = truncatedPng; // missing final IDAT chunk\nhslOp.run(buf, [0,0,0]); // -> Error loading image. (Jimp decode failed)\n// after\nconst buf = await repairOrReencodeToPng(truncatedPng);\nhslOp.run(buf, [0,0,0]);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await hslOp.run(buf, [hue, sat, light]);\n} catch (e) {\n  if (e instanceof OperationError && /Error loading image/.test(e.message)) {\n    // Jimp rejected the body: re-encode the source or report a corrupt-file error.\n    reportCorruptImage(e.message);\n  } else throw e;\n}","preventionTips":["Re-encode untrusted images to PNG before processing.","Validate buffer length against the image header before calling.","Pin a known-good jimp version.","Treat Jimp 'Unsupported MIME' errors as recoverable, not fatal."],"tags":["image","jimp","decoding","cyberchef","error-handling"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}