gchq/CyberChef · error · OperationError
Typex must have 5 rotors
Error message
Typex must have 5 rotors
What it means
Thrown by the TypexMachine constructor in Typex.mjs when the rotors array does not contain exactly 5 entries. Typex is a five-rotor cipher machine (the right-most two rotors are static, the left three step), so any other count is a configuration error. The check runs after the superclass (EnigmaBase) constructor, so the rotor array must be valid Enigma rotors first.
Source
Thrown at src/core/lib/Typex.mjs:60
for (const i of Object.keys(KEYBOARD)) {
KEYBOARD_REV[KEYBOARD[i]] = i;
}
/**
* Typex machine. A lot like the Enigma, but five rotors, of which the first two are static.
*/
export class TypexMachine extends Enigma.EnigmaBase {
/**
* TypexMachine constructor.
*
* @param {Object[]} rotors - List of Rotors.
* @param {Object} reflector - A Reflector.
* @param {Plugboard} plugboard - A Plugboard.
*/
constructor(rotors, reflector, plugboard, keyboard) {
super(rotors, reflector, plugboard);
if (rotors.length !== 5) {
throw new OperationError("Typex must have 5 rotors");
}
this.keyboard = keyboard;
}
/**
* This is the same as the Enigma step function, it's just that the right-
* most two rotors are static.
*/
step() {
const r0 = this.rotors[2];
const r1 = this.rotors[3];
r0.step();
// The second test here is the double-stepping anomaly
if (r0.steps.has(r0.pos) || r1.steps.has(Utils.mod(r1.pos + 1, 26))) {
r1.step();
if (r1.steps.has(r1.pos)) {
const r2 = this.rotors[4];
r2.step();View on GitHub (pinned to 4290ea7539)
Solutions
- Provide exactly 5 rotors: rotors[0] and rotors[1] are static, rotors[2..4] step. Order is left-to-right as for Enigma.
- If migrating Enigma config, append two valid static rotors (any valid rotor wiring; they do not step).
- Validate rotors.length === 5 before constructing so the error is caught at config-load time with a clearer message.
Example fix
// before: only 3 rotors supplied new TypexMachine([r1, r2, r3], reflector, plugboard, "Encrypt"); // after: 5 rotors, first two static new TypexMachine([static1, static2, r1, r2, r3], reflector, plugboard, "Encrypt");
Defensive patterns
Strategy: validation
Validate before calling
if (!Array.isArray(rotors) || rotors.length !== 5) {
throw new Error(
`Typex requires exactly 5 rotors (2 static + 3 stepping). Got ${rotors?.length}.`
);
}
const machine = new TypexMachine(rotors, reflector, plugboard, keyboard); Type guard
function isTypexRotorSet(rotors) {
return Array.isArray(rotors) && rotors.length === 5;
} Try / catch
try {
machine = new TypexMachine(rotors, reflector, plugboard, keyboard);
} catch (e) {
if (e instanceof OperationError && /Typex must have 5 rotors/.test(e.message)) {
return { error: `Configure 5 Typex rotors (first two static) instead of ${rotors.length}.` };
}
throw e;
} Prevention
- Build rotor arrays from a Typex-specific config schema that has 5 slots, not the 3-slot Enigma schema.
- Validate the count at config load, before constructing the machine.
- Remember rotors[0] and rotors[1] are static; rotors[2..4] step.
When it happens
Trigger: Constructing `new TypexMachine(rotors, reflector, plugboard, keyboard)` with rotors.length !== 5. Common: passing an Enigma-style 3-rotor array, omitting the two static rotors, or building the rotor list from a config that only listed the stepping rotors.
Common situations: Reusing Enigma rotor-setup code (3 rotors) for Typex; UI that only collects 3 rotor selections; config schema migrated from Enigma without adding the two static rotor slots.
Related errors
- Plugboard wiring must be 26 unique uppercase letters
- Invalid block cipher mode: ${mode}
- Invalid ciphertext length: ${originalLength} bytes. Must be
- No padding requested but input is not a ${blockSize}-byte mu
- Unknown padding type: ${padding}
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/5d1e6f7c415920d9.
Report an issue: GitHub.