gchq/CyberChef · error · OperationError
M37 custom lugs must be 37 long and can only include . or x
Error message
M37 custom lugs must be 37 long and can only include . or x
What it means
Thrown by the Lorenz operation only when 'Wheel Pattern' is 'Custom'. The Μ37 motor wheel has 37 cams, so its lug pattern must be exactly 37 characters matching ^[.xX]*$. Guard is on line 287 of src/core/operations/Lorenz.mjs.
Source
Thrown at src/core/operations/Lorenz.mjs:287
if (s5<1 || s5>59) throw new OperationError("Ψ5 start must be between 1 and 59");
if (m37<1 || m37>37) throw new OperationError("Μ37 start must be between 1 and 37");
if (m61<1 || m61>61) throw new OperationError("Μ61 start must be between 1 and 61");
if (x1<1 || x1>41) throw new OperationError("Χ1 start must be between 1 and 41");
if (x2<1 || x2>31) throw new OperationError("Χ2 start must be between 1 and 31");
if (x3<1 || x3>29) throw new OperationError("Χ3 start must be between 1 and 29");
if (x4<1 || x4>26) throw new OperationError("Χ4 start must be between 1 and 26");
if (x5<1 || x5>23) throw new OperationError("Χ5 start must be between 1 and 23");
// Initialise chosen wheel pattern
let chosenSetting = "";
if (pattern === "Custom") {
const re = new RegExp("^[.xX]*$");
if (lugs1.length !== 43 || !re.test(lugs1)) throw new OperationError("Ψ1 custom lugs must be 43 long and can only include . or x ");
if (lugs2.length !== 47 || !re.test(lugs2)) throw new OperationError("Ψ2 custom lugs must be 47 long and can only include . or x");
if (lugs3.length !== 51 || !re.test(lugs3)) throw new OperationError("Ψ3 custom lugs must be 51 long and can only include . or x");
if (lugs4.length !== 53 || !re.test(lugs4)) throw new OperationError("Ψ4 custom lugs must be 53 long and can only include . or x");
if (lugs5.length !== 59 || !re.test(lugs5)) throw new OperationError("Ψ5 custom lugs must be 59 long and can only include . or x");
if (lugm37.length !== 37 || !re.test(lugm37)) throw new OperationError("M37 custom lugs must be 37 long and can only include . or x");
if (lugm61.length !== 61 || !re.test(lugm61)) throw new OperationError("M61 custom lugs must be 61 long and can only include . or x");
if (lugx1.length !== 41 || !re.test(lugx1)) throw new OperationError("Χ1 custom lugs must be 41 long and can only include . or x");
if (lugx2.length !== 31 || !re.test(lugx2)) throw new OperationError("Χ2 custom lugs must be 31 long and can only include . or x");
if (lugx3.length !== 29 || !re.test(lugx3)) throw new OperationError("Χ3 custom lugs must be 29 long and can only include . or x");
if (lugx4.length !== 26 || !re.test(lugx4)) throw new OperationError("Χ4 custom lugs must be 26 long and can only include . or x");
if (lugx5.length !== 23 || !re.test(lugx5)) throw new OperationError("Χ5 custom lugs must be 23 long and can only include . or x");
chosenSetting = INIT_PATTERNS["No Pattern"];
chosenSetting.S[1] = this.readLugs(lugs1);
chosenSetting.S[2] = this.readLugs(lugs2);
chosenSetting.S[3] = this.readLugs(lugs3);
chosenSetting.S[4] = this.readLugs(lugs4);
chosenSetting.S[5] = this.readLugs(lugs5);
chosenSetting.M[1] = this.readLugs(lugm61);
chosenSetting.M[2] = this.readLugs(lugm37);
chosenSetting.X[1] = this.readLugs(lugx1);
chosenSetting.X[2] = this.readLugs(lugx2);
chosenSetting.X[3] = this.readLugs(lugx3);
chosenSetting.X[4] = this.readLugs(lugx4);View on GitHub (pinned to 4290ea7539)
Solutions
- Provide a Μ37 lugs string of exactly 37 characters using only '.', 'x', 'X'.
- Edit a known-good 37-character pattern in place.
- Pre-validate with /^[.xX]{37}$/ before running.
Example fix
// before: args[24] = "x.x" (3 chars) -> throws // after: args[24] = "x.x.x.x.x.x...x.x.x...x.x.x...x.x...." (37 chars) -> ok
Defensive patterns
Strategy: validation
Validate before calling
// Μ37 lugs (args[24]) must match /^[.xX]{37}$/ when pattern === 'Custom'.
function validateCustomLugs(str, size, name) {
if (typeof str !== "string" || !new RegExp(`^[.xX]{${size}}$`).test(str)) {
throw new Error(`${name} lugs must be exactly ${size} chars of '.', 'x', or 'X'`);
}
}
if (args[1] === "Custom") validateCustomLugs(args[24], 37, "M37"); Type guard
const isMu37Lugs = (s) => typeof s === "string" && /^[.xX]{37}$/.test(s); Try / catch
try {
lorenz.run(input, args);
} catch (err) {
if (err instanceof OperationError && /M37 custom lugs/.test(err.message)) {
args[24] = "x.x.x.x.x.x...x.x.x...x.x.x...x.x...."; // known-good 37-char pattern
} else throw err;
} Prevention
- The two motor wheels have different cam counts; Μ37 needs exactly 37 characters.
- Do not paste a Μ61 (61-char) string into the Μ37 field.
- Validate with /^[.xX]{37}$/ before running.
When it happens
Trigger: Calling Lorenz.run() with pattern='Custom' where args[24] (Μ37 lugs) is not exactly 37 characters or contains characters other than '.', 'x', 'X'.
Common situations: Custom pattern with a Μ37 string copied from Μ61 (61 chars) or a psi wheel; truncation on paste; invalid characters added while editing.
Related errors
- M61 custom lugs must be 61 long and can only include . or x
- Ψ1 custom lugs must be 43 long and can only include . or x
- Ψ2 custom lugs must be 47 long and can only include . or x
- Ψ3 custom lugs must be 51 long and can only include . or x
- Ψ4 custom lugs must be 53 long and can only include . or x
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/2408e6c68d995f88.
Report an issue: GitHub.