gchq/CyberChef · error · OperationError

Invalid file type.

Error message

Invalid file type.

What it means

Thrown at the top of ImageHueSaturationLightness.run() because isImage(input) returned falsy before Jimp ever sees the data. CyberChef's isImage (src/core/lib/FileType.mjs:240) matches image magic bytes (PNG/JPEG/GIF/BMP/etc.); any non-image or unrecognized signature fails. It is an OperationError, so the recipe surfaces it as the step's output instead of crashing the chain.

Source

Thrown at src/core/operations/ImageHueSaturationLightness.mjs:66

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

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

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Run the 'Detect File Type' op on the input to confirm it is actually an image.
  2. Make sure the upstream step outputs an image ArrayBuffer (e.g. render/decode to PNG first).
  3. Set the op's input type to match the real data (File vs Hex vs Base64).
  4. For exotic formats, convert the source to PNG/JPEG before this operation.

Example fix

// before
const buf = new TextEncoder().encode('hello').buffer;
hslOp.run(buf, [0, 0, 0]); // throws 'Invalid file type.'
// after
import { isImage } from "src/core/lib/FileType.mjs";
if (isImage(pngBuffer) === false) throw new Error('feed a real image');
hslOp.run(pngBuffer, [0, 0, 0]);
Defensive patterns

Strategy: validation

Validate before calling

import { isImage } from "src/core/lib/FileType.mjs";
const buf8 = input instanceof Uint8Array ? input : new Uint8Array(input);
if (isImage(buf8) === false) {
  throw new Error('Input is not a recognized image; cannot run HSL op.');
}

Type guard

import { isImage } from "src/core/lib/FileType.mjs";
function isImageBuffer(buf) {
  const u8 = buf instanceof Uint8Array ? buf : new Uint8Array(buf);
  return typeof isImage(u8) === 'string'; // mime string, not false
}

Prevention

When it happens

Trigger: run(input, args) is called with an ArrayBuffer whose leading bytes are not a known image signature: pasted text, a hex/PE/zip blob, or an image whose header was stripped. Also when the previous recipe step's outputType is not an ArrayBuffer image (e.g. a decoder feeding raw bytes) and the op input-type selector disagrees.

Common situations: Pasting plain text or hex into the op, chaining after a decode/extract step whose output is not an image, or feeding a modern format (AVIF/HEIC/WebP variants) absent from the signature DB. Re-selecting input format after the buffer changed also mismatches.

Related errors


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