gchq/CyberChef · error · OperationError

${name} connects ${pair[1]} more than once

Error message

${name} connects ${pair[1]} more than once

What it means

Thrown by PairMapBase (the shared base for Enigma Plugboard and Reflector) during construction. The pairs string is split on whitespace and each two-letter pair wires two letters together bijectively; a letter may only appear in a single pair. This specific throw fires on the SECOND letter of a new pair when that letter was already wired by a previous pair (e.g. "AB CB" reuses B). It reports the offending letter via the component name passed in ("Plugboard"/"Reflector").

Source

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

        this.pairs = pairs;
        this.map = {};
        if (pairs === "") {
            return;
        }
        pairs.split(/\s+/).forEach(pair => {
            if (!/^[A-Z]{2}$/.test(pair)) {
                throw new OperationError(name + " must be a whitespace-separated list of uppercase letter pairs");
            }
            const a = a2i(pair[0]), b = a2i(pair[1]);
            if (a === b) {
                // self-stecker
                return;
            }
            if (Object.prototype.hasOwnProperty.call(this.map, a)) {
                throw new OperationError(`${name} connects ${pair[0]} more than once`);
            }
            if (Object.prototype.hasOwnProperty.call(this.map, b)) {
                throw new OperationError(`${name} connects ${pair[1]} more than once`);
            }
            this.map[a] = b;
            this.map[b] = a;
        });
    }

    /**
     * Transform a character through this object.
     * Returns other characters unchanged.
     *
     * @param {number} c - The character.
     * @returns {number}
     */
    transform(c) {
        if (!Object.prototype.hasOwnProperty.call(this.map, c)) {
            return c;
        }
        return this.map[c];

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Scan the pairs string for any letter that appears in more than one non-self pair and remove the duplicate.
  2. Re-verify against the intended wiring table (every letter A-Z at most once, except self-stecker pairs like 'AA' which are no-ops).
  3. Build pairs programmatically and assert uniqueness before passing to the constructor.

Example fix

// before
new Plugboard("AB CD BF"); // B wired twice (AB and BF)

// after
new Plugboard("AB CD EF"); // each letter appears once
Defensive patterns

Strategy: validation

Validate before calling

function validatePairs(pairs, name = "PairMapBase") {
  if (pairs === "") return;
  const seen = new Set();
  for (const pair of pairs.split(/\s+/)) {
    if (!/^[A-Z]{2}$/.test(pair)) throw new Error(`${name} pair '${pair}' is not two uppercase letters`);
    if (pair[0] === pair[1]) continue; // self-stecker, skipped by lib
    for (const ch of pair) {
      if (seen.has(ch)) throw new Error(`${name} connects ${ch} more than once`);
      seen.add(ch);
    }
  }
}
validatePairs(plugboardStr, "Plugboard");
new Plugboard(plugboardStr);

Type guard

function isUniquePairs(pairs) {
  if (pairs === "") return true;
  const seen = new Set();
  for (const pair of pairs.split(/\s+/)) {
    if (!/^[A-Z]{2}$/.test(pair)) return false;
    if (pair[0] === pair[1]) continue;
    for (const ch of pair) { if (seen.has(ch)) return false; seen.add(ch); }
  }
  return true;
}

Try / catch

try {
  new Plugboard(plugboardStr);
} catch (err) {
  if (err instanceof OperationError && /connects .* more than once/.test(err.message)) {
    // surface to user: duplicate letter in pairs
  } else throw err;
}

Prevention

When it happens

Trigger: Constructing `new Plugboard("AB CB")`, `new Reflector("AB BC BD ...")`, or any PairMapBase subclass where a letter recurs as the second element of a later pair. Self-stecker pairs like "AA" are silently skipped (early return) and do NOT seed the map, so they never trigger this.

Common situations: Typo or copy-paste duplication in a plugboard/reflector recipe argument; transcribing a historical reflector wiring and repeating a letter; mixing two stecker tables together without de-duplicating.

Related errors


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