gchq/CyberChef · error · OperationError

Typex must have 5 rotors

Error message

Typex must have 5 rotors

What it means

Thrown by the TypexMachine constructor in Typex.mjs when the rotors array does not contain exactly 5 entries. Typex is a five-rotor cipher machine (the right-most two rotors are static, the left three step), so any other count is a configuration error. The check runs after the superclass (EnigmaBase) constructor, so the rotor array must be valid Enigma rotors first.

Source

Thrown at src/core/lib/Typex.mjs:60

for (const i of Object.keys(KEYBOARD)) {
    KEYBOARD_REV[KEYBOARD[i]] = i;
}

/**
 * Typex machine. A lot like the Enigma, but five rotors, of which the first two are static.
 */
export class TypexMachine extends Enigma.EnigmaBase {
    /**
     * TypexMachine constructor.
     *
     * @param {Object[]} rotors - List of Rotors.
     * @param {Object} reflector - A Reflector.
     * @param {Plugboard} plugboard - A Plugboard.
     */
    constructor(rotors, reflector, plugboard, keyboard) {
        super(rotors, reflector, plugboard);
        if (rotors.length !== 5) {
            throw new OperationError("Typex must have 5 rotors");
        }
        this.keyboard = keyboard;
    }

    /**
     * This is the same as the Enigma step function, it's just that the right-
     * most two rotors are static.
     */
    step() {
        const r0 = this.rotors[2];
        const r1 = this.rotors[3];
        r0.step();
        // The second test here is the double-stepping anomaly
        if (r0.steps.has(r0.pos) || r1.steps.has(Utils.mod(r1.pos + 1, 26))) {
            r1.step();
            if (r1.steps.has(r1.pos)) {
                const r2 = this.rotors[4];
                r2.step();

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Provide exactly 5 rotors: rotors[0] and rotors[1] are static, rotors[2..4] step. Order is left-to-right as for Enigma.
  2. If migrating Enigma config, append two valid static rotors (any valid rotor wiring; they do not step).
  3. Validate rotors.length === 5 before constructing so the error is caught at config-load time with a clearer message.

Example fix

// before: only 3 rotors supplied
new TypexMachine([r1, r2, r3], reflector, plugboard, "Encrypt");
// after: 5 rotors, first two static
new TypexMachine([static1, static2, r1, r2, r3], reflector, plugboard, "Encrypt");
Defensive patterns

Strategy: validation

Validate before calling

if (!Array.isArray(rotors) || rotors.length !== 5) {
    throw new Error(
        `Typex requires exactly 5 rotors (2 static + 3 stepping). Got ${rotors?.length}.`
    );
}
const machine = new TypexMachine(rotors, reflector, plugboard, keyboard);

Type guard

function isTypexRotorSet(rotors) {
    return Array.isArray(rotors) && rotors.length === 5;
}

Try / catch

try {
    machine = new TypexMachine(rotors, reflector, plugboard, keyboard);
} catch (e) {
    if (e instanceof OperationError && /Typex must have 5 rotors/.test(e.message)) {
        return { error: `Configure 5 Typex rotors (first two static) instead of ${rotors.length}.` };
    }
    throw e;
}

Prevention

When it happens

Trigger: Constructing `new TypexMachine(rotors, reflector, plugboard, keyboard)` with rotors.length !== 5. Common: passing an Enigma-style 3-rotor array, omitting the two static rotors, or building the rotor list from a config that only listed the stepping rotors.

Common situations: Reusing Enigma rotor-setup code (3 rotors) for Typex; UI that only collects 3 rotor selections; config schema migrated from Enigma without adding the two static rotor slots.

Related errors


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