gchq/CyberChef · error · OperationError

Invalid file type.

Error message

Invalid file type.

What it means

Thrown at the top of Image Brightness/Contrast run() when isImage(input) returns false. isImage sniffs magic bytes against known image types (PNG/JPEG/GIF/BMP/WebP etc.). If the leading bytes do not match any image signature the buffer is rejected before Jimp is ever called.

Source

Thrown at src/core/operations/ImageBrightnessContrast.mjs:57

            {
                name: "Contrast",
                type: "number",
                value: 0,
                min: -100,
                max: 100,
            },
        ];
    }

    /**
     * @param {ArrayBuffer} input
     * @param {Object[]} args
     * @returns {byteArray}
     */
    async run(input, args) {
        const [brightness, contrast] = 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 (brightness !== 0) {
                if (isWorkerEnvironment())
                    self.sendStatusMessage("Changing image brightness...");
                image.brightness(brightness / 100);
            }
            if (contrast !== 0) {
                if (isWorkerEnvironment())
                    self.sendStatusMessage("Changing image contrast...");
                image.contrast(contrast / 100);

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Verify the input ArrayBuffer is a complete, valid raster image.
  2. If the data is base64/hex, run From Base64 / From Hex first.
  3. Check for an empty buffer (byteLength === 0) before invoking.
  4. For SVG, rasterise to PNG/JPEG first - Jimp does not read SVG.

Example fix

// before: raw base64 string fed directly
op.run(base64String, [10, 10]);
// after: decode to bytes first
const buf = fromBase64(base64String).buffer;
op.run(buf, [10, 10]);
Defensive patterns

Strategy: type-guard

Validate before calling

import { isImage } from "../lib/FileType.mjs";
function assertImageInput(buf) {
  if (!isImage(buf)) throw new Error('Input is not a recognised image type');
}

Type guard

function isImageInput(buf) {
  return buf instanceof ArrayBuffer ? isImage(new Uint8Array(buf)) : !!isImage(buf);
}

Try / catch

try {
  result = await brightness.run(buf, [b, c]);
} catch (e) {
  if (e instanceof OperationError && /Invalid file type/.test(e.message)) {
    // not an image - skip or convert first
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: Feeding a non-image file (text, PDF, archive, executable); a truncated or empty ArrayBuffer; a buffer whose magic bytes were corrupted; wrong file dropped into the recipe.

Common situations: Operation placed after a decode/gunzip that produced non-image output; feeding a base64 blob that was not yet From Base64 decoded; a SVG (no sniffable magic bytes in the raster sense); an empty input from a previous failed op.

Related errors


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