gchq/CyberChef · error · OperationError

Invalid file type.

Error message

Invalid file type.

What it means

Thrown by Dither Image run() when isImage(input) returns falsy on the input ArrayBuffer - i.e. the bytes do not begin with a recognized image magic signature (PNG/JPEG/GIF/BMP/WebP). Dithering requires a decodable raster image; this guard runs before Jimp.read(). It fires on the run/crop path, distinct from the present() 'Invalid file type.' error which fires during rendering.

Source

Thrown at src/core/operations/DitherImage.mjs:41

        this.name = "Dither Image";
        this.module = "Image";
        this.description = "Apply a dither effect to an image.";
        this.infoURL = "https://wikipedia.org/wiki/Dither";
        this.inputType = "ArrayBuffer";
        this.outputType = "ArrayBuffer";
        this.presentType = "html";
        this.args = [];
    }

    /**
     * @param {ArrayBuffer} input
     * @param {Object[]} args
     * @returns {byteArray}
     */
    async run(input, args) {
        if (!isImage(input)) {
            throw new OperationError("Invalid file type.");
        }

        let image;
        try {
            image = await Jimp.read(input);
        } catch (err) {
            throw new OperationError(`Error loading image. (${err})`);
        }
        try {
            if (isWorkerEnvironment())
                self.sendStatusMessage("Applying dither to image...");
            image.dither();

            let imageBuffer;
            if (image.mime === "image/gif") {
                imageBuffer = await image.getBuffer(JimpMime.png);
            } else {
                imageBuffer = await image.getBuffer(image.mime);

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Confirm the input is a supported raster image (use Detect File Type or check the magic bytes).
  2. If the data is raw pixels, wrap it into a PNG/JPEG container first (e.g. via an image-encoding operation).
  3. Convert unsupported formats (HEIC/TIFF) to PNG/JPEG before Dither Image.
  4. Re-upload or re-extract the source image if it is truncated.

Example fix

// before - raw RGB pixels fed in
input: <raw RGB bytes>

// after - PNG-encoded image fed in
input: <PNG with header 89 50 4E 47 ...>
Defensive patterns

Strategy: validation

Validate before calling

import { isImage } from "src/core/lib/FileType.mjs";

function isImageBuffer(buf) {
    return buf instanceof ArrayBuffer && buf.byteLength > 0 && Boolean(isImage(new Uint8Array(buf)));
}

Type guard

/** @returns {boolean} */
function isDecodableImage(buf) {
    return buf instanceof ArrayBuffer
        && buf.byteLength > 0
        && Boolean(isImage(new Uint8Array(buf)));
}

Try / catch

try {
    out = await ditherImage.run(input, args);
} catch (e) {
    if (e instanceof OperationError && /Invalid file type/.test(e.message)) {
        // convert/encode the input to PNG/JPEG before retrying
    } else throw e;
}

Prevention

When it happens

Trigger: Feeding non-image bytes into Dither Image: a text/document ArrayBuffer, raw pixel data without a header, a truncated image, or an unsupported image format that isImage does not recognize. The check happens before any Jimp processing.

Common situations: Piping output of a non-image operation into Dither Image; an image format Jimp/isImage does not support (e.g. HEIC, TIFF in some configs); a truncated/corrupted image upload; raw RGB pixel data missing a container header.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/cb0ad9ee9c2028cc. Report an issue: GitHub.