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
- Scan the pairs string for any letter that appears in more than one non-self pair and remove the duplicate.
- Re-verify against the intended wiring table (every letter A-Z at most once, except self-stecker pairs like 'AA' which are no-ops).
- 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
- Generate plugboard/reflector pairs from a single source-of-truth table rather than hand-typing.
- Run a uniqueness assertion over the pairs string before construction.
- Remember self-stecker pairs like 'AA' are silently ignored and do not count toward coverage.
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
- ${name} connects ${pair[0]} more than once
- Reflector must have exactly 13 pairs covering every letter
- ${name} must be a whitespace-separated list of uppercase let
- Rotor wiring must be 26 unique uppercase letters
- A minimum of three rotors must be supplied
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/8403dbf79f71b4fe.
Report an issue: GitHub.