gchq/CyberChef · error · OperationError

Rotor initial position must be exactly one uppercase letter

Error message

Rotor initial position must be exactly one uppercase letter

What it means

Thrown by the Rotor constructor when initialPosition fails /^[A-Z]$/ — it must be exactly one uppercase ASCII letter representing the rotor's starting window position.

Source

Thrown at src/core/lib/Enigma.mjs:103

     * Rotor constructor.
     *
     * @param {string} wiring - A 26 character string of the wiring order.
     * @param {string} steps - A 0..26 character string of stepping points.
     * @param {char} ringSetting - The ring setting.
     * @param {char} initialPosition - The initial position of the rotor.
     */
    constructor(wiring, steps, ringSetting, initialPosition) {
        if (!/^[A-Z]{26}$/.test(wiring)) {
            throw new OperationError("Rotor wiring must be 26 unique uppercase letters");
        }
        if (!/^[A-Z]{0,26}$/.test(steps)) {
            throw new OperationError("Rotor steps must be 0-26 unique uppercase letters");
        }
        if (!/^[A-Z]$/.test(ringSetting)) {
            throw new OperationError("Rotor ring setting must be exactly one uppercase letter");
        }
        if (!/^[A-Z]$/.test(initialPosition)) {
            throw new OperationError("Rotor initial position must be exactly one uppercase letter");
        }
        this.map = new Array(26);
        this.revMap = new Array(26);
        const uniq = {};
        for (let i=0; i<LETTERS.length; i++) {
            const a = a2i(LETTERS[i]);
            const b = a2i(wiring[i]);
            this.map[a] = b;
            this.revMap[b] = a;
            uniq[b] = true;
        }
        if (Object.keys(uniq).length !== LETTERS.length) {
            throw new OperationError("Rotor wiring must have each letter exactly once");
        }
        const rs = a2i(ringSetting);
        this.steps = new Set();
        for (const x of steps) {
            this.steps.add(Utils.mod(a2i(x) - rs, 26));

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Convert numeric positions to letters: String.fromCharCode(64 + n) for n in 1-26.
  2. Pass exactly one uppercase letter.
  3. Validate /^[A-Z]$/.test(initialPosition) before constructing.

Example fix

// before
new Rotor('EKMFLGDQVZNTOWYHXUSPAIBRCJ', 'R', 'A', 1); // number

// after
new Rotor('EKMFLGDQVZNTOWYHXUSPAIBRCJ', 'R', 'A', 'A');
Defensive patterns

Strategy: validation

Validate before calling

function positionToLetter(n) {
  if (!Number.isInteger(n) || n < 1 || n > 26) throw new Error("Position must be 1-26.");
  return String.fromCharCode(64 + n);
}
const initialPosition = positionToLetter(numericPos);
if (!/^[A-Z]$/.test(initialPosition)) {
  throw new Error("Initial position must be one uppercase letter.");
}

Type guard

function isSingleUppercaseLetter(c) {
  return typeof c === "string" && /^[A-Z]$/.test(c);
}

Prevention

When it happens

Trigger: new Rotor(..., initialPosition) where initialPosition is empty, longer than one char, lowercase, a number (e.g. the common numeric 1-26 convention), or undefined.

Common situations: Passing a numeric starting position from historical settings tables instead of the letter A-Z; empty/undefined value; lowercase input.

Related errors


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