gchq/CyberChef · error · OperationError
${name} connects ${pair[0]} more than once
Error message
${name} connects ${pair[0]} more than once What it means
Thrown by the PairMapBase constructor when a letter appears in more than one pair — the map already has an entry for that letter. Each letter may be connected to at most one partner (self-stecker pairs like 'AA' are silently ignored). The error interpolates name (e.g. 'Plugboard' or 'Reflector') and the offending letter.
Source
Thrown at src/core/lib/Enigma.mjs:188
constructor(pairs, name="PairMapBase") {
// I've chosen to make whitespace significant here to make a) code and
// b) inputs easier to read
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)) {View on GitHub (pinned to 4290ea7539)
Solutions
- Ensure each letter appears in at most one pair across the whole spec.
- Before constructing, build a usage map and reject any letter seen twice.
- Deduplicate pairs and remove conflicting entries.
Example fix
// before
new Plugboard('AY AB CD'); // A connected to Y and B
// after
new Plugboard('AY BC DE'); // each letter unique Defensive patterns
Strategy: validation
Validate before calling
function hasNoDoubleConnect(pairs) {
const seen = new Set();
for (const tok of pairs.split(/\s+/).filter(Boolean)) {
const [a, b] = [tok[0], tok[1]];
if (a === b) continue; // self-stecker allowed
if (seen.has(a) || seen.has(b)) return false;
seen.add(a); seen.add(b);
}
return true;
}
if (!hasNoDoubleConnect(pairs)) {
throw new Error("Each letter may appear in at most one pair.");
} Type guard
function isNonOverlappingPairs(pairs) {
const seen = new Set();
for (const tok of pairs.split(/\s+/).filter(Boolean)) {
const [a, b] = [tok[0], tok[1]];
if (a === b) continue;
if (seen.has(a) || seen.has(b)) return false;
seen.add(a); seen.add(b);
}
return true;
} Prevention
- Track each letter's usage; reject specs binding a letter twice.
- Deduplicate and resolve conflicts before constructing.
- Remember a Reflector additionally needs all 13 pairs covering every letter.
When it happens
Trigger: new Plugboard('AY AB ...') or new Reflector(...) where 'A' is connected to both Y and B — the second pair triggers hasOwnProperty(map, a) and throws. Same for the partner letter (the b-side check covers reversed overlaps).
Common situations: Listing a plugboard connection twice for the same letter; copying a reflector spec that double-binds a letter; editing a pair and forgetting to remove the old one; overlapping pairs from merge errors.
Related errors
- ${name} must be a whitespace-separated list of uppercase let
- ${name} connects ${pair[1]} more than once
- Rotor wiring must be 26 unique uppercase letters
- Rotor steps must be 0-26 unique uppercase letters
- Rotor ring setting must be exactly one uppercase letter
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/fdbc678556daa81b.
Report an issue: GitHub.