gchq/CyberChef · error · OperationError

Rotor ${i} must be provided.

Error message

Rotor ${i} must be provided.

What it means

Thrown in Enigma.parseRotorStr when a rotor specification string is ''. Rotors are editableOption fields combining 26-letter wiring (and optional '<' stepping points) into one string; parseRotorStr splits it. An empty value means no rotor wiring for that slot, which is fatal because the machine cannot step/encipher without a rotor. The index i is interpolated to identify which slot (left-hand/middle/right-hand/fourth) is empty.

Source

Thrown at src/core/operations/Enigma.mjs:141

                name: "Strict output",
                hint: "Remove non-alphabet letters and group output",
                type: "boolean",
                value: true
            },
        ];
    }

    /**
     * Helper - for ease of use rotors are specified as a single string; this
     * method breaks the spec string into wiring and steps parts.
     *
     * @param {string} rotor - Rotor specification string.
     * @param {number} i - For error messages, the number of this rotor.
     * @returns {string[]}
     */
    parseRotorStr(rotor, i) {
        if (rotor === "") {
            throw new OperationError(`Rotor ${i} must be provided.`);
        }
        if (!rotor.includes("<")) {
            return [rotor, ""];
        }
        return rotor.split("<", 2);
    }

    /**
     * @param {string} input
     * @param {Object[]} args
     * @returns {string}
     */
    run(input, args) {
        const model = args[0];
        const reflectorstr = args[13];
        const plugboardstr = args[14];
        const removeOther = args[15];
        const rotors = [];

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Provide a valid rotor wiring string - a permutation of A-Z, optionally followed by '<' and stepping letters, e.g. 'EKMFLGDQVZNTOWYHXUSPAIBRCJ<Q'.
  2. Select a built-in rotor from the dropdown rather than clearing it.
  3. For imported recipes, ensure no rotor slot is empty before running.

Example fix

// before
parseRotorStr('', 2);                       // empty slot -> throws
// after
parseRotorStr('EKMFLGDQVZNTOWYHXUSPAIBRCJ<Q', 2);
Defensive patterns

Strategy: validation

Validate before calling

function parseRotor(rotor, i) {
  if (typeof rotor !== "string" || rotor === "") throw new Error(`rotor ${i} must be provided`);
  return rotor.includes("<") ? rotor.split("<", 2) : [rotor, ""];
}
// ensure every required rotor slot is non-empty before running Enigma
for (const [i, rot] of requiredRotors.entries()) parseRotor(rot, i);

Type guard

const isNonEmptyRotor = (s) => typeof s === "string" && s.length > 0;

Prevention

When it happens

Trigger: A rotor editableOption field was cleared so its value becomes '', a custom rotor string pasted as empty, or an imported recipe stored an empty rotor value. The Model argSelector toggles the 4th-rotor slot, so switching models with a stale empty value can expose it.

Common situations: Clearing a rotor field to type custom wiring and forgetting to fill it; loading a recipe saved with a blank rotor; switching between 3-rotor and 4-rotor models where the 4th slot was left empty.

Related errors


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