gchq/CyberChef · warning · OperationError
Error normalising image. (${err})
Error message
Error normalising image. (${err}) What it means
Thrown by parseQrCode when `image.greyscale()` or `image.normalize()` throws after a successful read. The original Jimp error is appended. This is rare and typically indicates an edge case in the decoded bitmap (e.g. unsupported colour space or zero-pixel image).
Source
Thrown at src/core/lib/QRCode.mjs:36
* @param {ArrayBuffer} input
* @param {boolean} normalise
* @returns {string}
*/
export async function parseQrCode(input, normalise) {
let image;
try {
image = await Jimp.read(input);
} catch (err) {
throw new OperationError(`Error opening image. (${err})`);
}
try {
if (normalise) {
image.greyscale();
image.normalize();
}
} catch (err) {
throw new OperationError(`Error normalising image. (${err})`);
}
// Remove transparency which jsQR cannot handle
image.scan((x, y, idx) => {
// If pixel is fully transparent, make it opaque white
if (image.bitmap.data[idx + 3] === 0x00) {
image.bitmap.data[idx + 0] = 0xff;
image.bitmap.data[idx + 1] = 0xff;
image.bitmap.data[idx + 2] = 0xff;
}
// Otherwise, make it fully opaque at its existing colour
image.bitmap.data[idx + 3] = 0xff;
});
image = await Jimp.read(await image.getBuffer(JimpMime.jpeg));
const qrData = jsQR(
new Uint8ClampedArray(image.bitmap.data),
image.width,View on GitHub (pinned to 4290ea7539)
Solutions
- Retry with normalise=false to bypass greyscale/normalise.
- Re-encode the source image to a standard 8-bit sRGB PNG before parsing.
- Check the Jimp version is compatible with this CyberChef build.
Example fix
// before await parseQrCode(input, true); // throws on degenerate image // after await parseQrCode(input, false);
Defensive patterns
Strategy: retry
Validate before calling
async function safeParseQr(input) {
try { return await parseQrCode(input, true); }
catch (e) { if (/normalising/.test(e.message)) return await parseQrCode(input, false); throw e; }
} Try / catch
try {
return await parseQrCode(input, true);
} catch (e) {
if (e instanceof OperationError && /normalising/.test(e.message)) {
return await parseQrCode(input, false); // retry without normalise
}
throw e;
} Prevention
- Default to normalise=false for unusual/16-bit images.
- Re-encode sources to 8-bit sRGB PNG first.
- Keep Jimp version aligned with the CyberChef build.
When it happens
Trigger: Calling parseQrCode(input, true) where the image decodes but Jimp's pixel operations fail — degenerate dimensions (0x0), unusual bit depth, or a Jimp version regression.
Common situations: Passing normalise=true with an image Jimp decoded only partially; Jimp/library version mismatch after upgrade; CMYK/16-bit images that Jimp represents oddly.
Related errors
- Error opening image. (${err})
- Could not read a QR code from the image.
- Invalid file type.
- Error loading image. (${err})
- Error preparing fonts. (${err})
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/421b2b92dc1cecaf.
Report an issue: GitHub.