{"record":{"id":"97f44a727dd6b064","repo":"gchq/CyberChef","slug":"error-loading-image-err-97f44a","errorCode":null,"errorMessage":"Error loading image. (${err})","messagePattern":"Error loading image\\. \\((.+?)\\)","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"warning","filePath":"src/core/operations/ImageBrightnessContrast.mjs","lineNumber":64,"sourceCode":"        ];\n    }\n\n    /**\n     * @param {ArrayBuffer} input\n     * @param {Object[]} args\n     * @returns {byteArray}\n     */\n    async run(input, args) {\n        const [brightness, contrast] = args;\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 (brightness !== 0) {\n                if (isWorkerEnvironment())\n                    self.sendStatusMessage(\"Changing image brightness...\");\n                image.brightness(brightness / 100);\n            }\n            if (contrast !== 0) {\n                if (isWorkerEnvironment())\n                    self.sendStatusMessage(\"Changing image contrast...\");\n                image.contrast(contrast / 100);\n            }\n\n            let imageBuffer;\n            if (image.mime === \"image/gif\") {\n                imageBuffer = await image.getBuffer(JimpMime.png);\n            } else {\n                imageBuffer = await image.getBuffer(image.mime);","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/ImageBrightnessContrast.mjs#L46-L82","documentation":"Thrown when Jimp.read(input) rejects while loading the image inside Image Brightness/Contrast. This fires only after isImage passed, so the magic bytes looked plausible but the actual decode failed. The original Jimp error is interpolated into the message.","triggerScenarios":"Truncated image (magic bytes present but body incomplete); corrupt pixel data; a format Jimp does not support despite a sniffable header (e.g. some WebP/HEIC variants, progressive JPEG edge cases); a buffer that is actually a container (e.g. a SVG with PNG-like bytes).","commonSituations":"Partial download/capture; conversion artefact from another tool; version mismatch where the bundled Jimp lacks a codec; very large image exceeding Jimp's memory.","solutions":["Read the interpolated Jimp error for the specific failure reason.","Re-export or re-download the source image to ensure it is complete and uncorrupted.","Convert the image to PNG/JPEG with an external tool before invoking.","Check the bundled Jimp version supports the image's subformat."],"exampleFix":"// before: feeding a truncated buffer whose header survived but body did not\nop.run(truncatedPngBuf, [10, 10]);\n// after: feed the complete file\nop.run(completePngBuf, [10, 10]);","handlingStrategy":"try-catch","validationCode":"async function assertJimpReadable(buf) {\n  try { await Jimp.read(buf); }\n  catch (e) { throw new Error(`Jimp cannot read this image: ${e}`); }\n}","typeGuard":null,"tryCatchPattern":"try {\n  result = await brightness.run(buf, [b, c]);\n} catch (e) {\n  if (e instanceof OperationError && /Error loading image/.test(e.message)) {\n    // re-supply a complete source image\n    result = await brightness.run(await reload(fullUrl), [b, c]);\n  } else throw e;\n}","preventionTips":["Ensure the source image is complete and uncorrupted.","Pre-convert exotic formats to PNG/JPEG.","Confirm the bundled Jimp version supports the subformat."],"tags":["image","jimp","decode-error","corrupt-file"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}