gchq/CyberChef · error · OperationError

Offset cannot be negative

Error message

Offset cannot be negative

What it means

Thrown by MultipleBombe.run when the offset (args[5]) is less than zero. The offset marks where in the ciphertext the crib begins; a negative offset would slice the ciphertext backwards, which is meaningless, so it is rejected.

Source

Thrown at src/core/operations/MultipleBombe.mjs:220

                rstr = this.validateRotor(rstr);
                fourthRotors.push(rstr);
            }
        }
        if (fourthRotors.length === 0) {
            fourthRotors.push("");
        }
        for (const rstr of reflectorsStr.split("\n")) {
            const reflector = new Reflector(rstr);
            reflectors.push(reflector);
        }
        if (reflectors.length === 0) {
            throw new OperationError("A minimum of one reflector must be supplied");
        }
        if (crib.length === 0) {
            throw new OperationError("Crib cannot be empty");
        }
        if (offset < 0) {
            throw new OperationError("Offset cannot be negative");
        }
        // For symmetry with the Enigma op, for the input we'll just remove all invalid characters
        input = input.replace(/[^A-Za-z]/g, "").toUpperCase();
        crib = crib.replace(/[^A-Za-z]/g, "").toUpperCase();
        const ciphertext = input.slice(offset);
        let update;
        if (isWorkerEnvironment()) {
            update = this.updateStatus;
        } else {
            update = undefined;
        }
        let bombe = undefined;
        const output = {bombeRuns: []};
        // I could use a proper combinatorics algorithm here... but it would be more code to
        // write one, and we don't seem to have one in our existing libraries, so massively nested
        // for loop it is
        const totalRuns = choose(rotors.length, 3) * 6 * fourthRotors.length * reflectors.length;
        let nRuns = 0;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Set the offset to 0 or a positive integer not exceeding the ciphertext length.
  2. If computing the offset, clamp with Math.max(0, value).
  3. Verify the crib's start position in the ciphertext.

Example fix

// before
chef.bake("Multiple Bombe", [..., "WETTER", -5, true]);
// after
chef.bake("Multiple Bombe", [..., "WETTER", 0, true]);
Defensive patterns

Strategy: validation

Validate before calling

const offset = args[5];
if (typeof offset !== "number" || offset < 0) {
  // set offset to 0 or a positive integer
}

Type guard

const isNonNegativeInt = (n) => Number.isInteger(n) && n >= 0;

Try / catch

try { chef.bake("Multiple Bombe", args); }
catch (e) { if (e.message === "Offset cannot be negative") resetOffset(); else throw e; }

Prevention

When it happens

Trigger: run(input, args) where args[5] < 0. The argument is a number type; a negative value (e.g. -1) passed via the recipe or UI spinner trips this immediately.

Common situations: Spinner dragged below zero; recipe JSON edited to a negative offset; offset computed from an upstream operation that underflowed; sign error when computing crib position.

Related errors


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