{"record":{"id":"f8a4efbeac6feb29","repo":"gchq/CyberChef","slug":"1-custom-lugs-must-be-41-long-and-can-only-includ","errorCode":null,"errorMessage":"Χ1 custom lugs must be 41 long and can only include . or x","messagePattern":"Χ1 custom lugs must be 41 long and can only include \\. or x","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/Lorenz.mjs","lineNumber":289,"sourceCode":"        if (m61<1 || m61>61) throw new OperationError(\"Μ61 start must be between 1 and 61\");\n        if (x1<1 || x1>41) throw new OperationError(\"Χ1 start must be between 1 and 41\");\n        if (x2<1 || x2>31) throw new OperationError(\"Χ2 start must be between 1 and 31\");\n        if (x3<1 || x3>29) throw new OperationError(\"Χ3 start must be between 1 and 29\");\n        if (x4<1 || x4>26) throw new OperationError(\"Χ4 start must be between 1 and 26\");\n        if (x5<1 || x5>23) throw new OperationError(\"Χ5 start must be between 1 and 23\");\n\n        // Initialise chosen wheel pattern\n        let chosenSetting = \"\";\n        if (pattern === \"Custom\") {\n            const re = new RegExp(\"^[.xX]*$\");\n            if (lugs1.length !== 43 || !re.test(lugs1)) throw new OperationError(\"Ψ1 custom lugs must be 43 long and can only include . or x \");\n            if (lugs2.length !== 47 || !re.test(lugs2)) throw new OperationError(\"Ψ2 custom lugs must be 47 long and can only include . or x\");\n            if (lugs3.length !== 51 || !re.test(lugs3)) throw new OperationError(\"Ψ3 custom lugs must be 51 long and can only include . or x\");\n            if (lugs4.length !== 53 || !re.test(lugs4)) throw new OperationError(\"Ψ4 custom lugs must be 53 long and can only include . or x\");\n            if (lugs5.length !== 59 || !re.test(lugs5)) throw new OperationError(\"Ψ5 custom lugs must be 59 long and can only include . or x\");\n            if (lugm37.length !== 37 || !re.test(lugm37)) throw new OperationError(\"M37 custom lugs must be 37 long and can only include . or x\");\n            if (lugm61.length !== 61 || !re.test(lugm61)) throw new OperationError(\"M61 custom lugs must be 61 long and can only include . or x\");\n            if (lugx1.length !== 41 || !re.test(lugx1)) throw new OperationError(\"Χ1 custom lugs must be 41 long and can only include . or x\");\n            if (lugx2.length !== 31 || !re.test(lugx2)) throw new OperationError(\"Χ2 custom lugs must be 31 long and can only include . or x\");\n            if (lugx3.length !== 29 || !re.test(lugx3)) throw new OperationError(\"Χ3 custom lugs must be 29 long and can only include . or x\");\n            if (lugx4.length !== 26 || !re.test(lugx4)) throw new OperationError(\"Χ4 custom lugs must be 26 long and can only include . or x\");\n            if (lugx5.length !== 23 || !re.test(lugx5)) throw new OperationError(\"Χ5 custom lugs must be 23 long and can only include . or x\");\n            chosenSetting = INIT_PATTERNS[\"No Pattern\"];\n            chosenSetting.S[1] = this.readLugs(lugs1);\n            chosenSetting.S[2] = this.readLugs(lugs2);\n            chosenSetting.S[3] = this.readLugs(lugs3);\n            chosenSetting.S[4] = this.readLugs(lugs4);\n            chosenSetting.S[5] = this.readLugs(lugs5);\n            chosenSetting.M[1] = this.readLugs(lugm61);\n            chosenSetting.M[2] = this.readLugs(lugm37);\n            chosenSetting.X[1] = this.readLugs(lugx1);\n            chosenSetting.X[2] = this.readLugs(lugx2);\n            chosenSetting.X[3] = this.readLugs(lugx3);\n            chosenSetting.X[4] = this.readLugs(lugx4);\n            chosenSetting.X[5] = this.readLugs(lugx5);\n        } else {","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/Lorenz.mjs#L271-L307","documentation":"Thrown by the Lorenz SZ operation when 'Wheel Pattern' is set to 'Custom' and the Χ1 (chi-1) lug string does not meet the hardware-accurate wheel size. The Χ1 wheel has exactly 41 lug positions, so the value supplied via arg[26] ('Χ1 lugs (41)') must be exactly 41 characters long and contain only '.', 'x', or 'X'. The check combines a length test with the regex /^[.xX]*$/, so either a wrong length or an illegal character triggers it.","triggerScenarios":"Selecting pattern='Custom' in the Lorenz operation and supplying a lugx1 string whose length is not exactly 41, or which contains any character other than '.', 'x', 'X' (e.g. spaces, '0'/'1', '-', 'o'). The check at Lorenz.mjs:289 fires before the wheel pattern is read via this.readLugs().","commonSituations":"Copying a lug pattern from a table/source that uses a different symbol convention (e.g. '1'/'0' instead of 'x'/'.'); pasting a Χ2/Ψ pattern into the Χ1 field by mistake; trimming or padding the string so it is 40 or 42 chars; leaving a trailing newline or space in the field.","solutions":["Set the Χ1 lug string to exactly 41 characters composed only of '.', 'x', or 'X' (41 is the fixed cam count of the physical chi-1 wheel).","If you do not need a custom wheel, switch 'Wheel Pattern' from 'Custom' to one of the preset patterns (KH, ZMUG, BREAM, No Pattern) — the validation only runs when pattern === 'Custom'.","Verify length and alphabet programmatically before invoking the operation (see validationCode).","Double-check you are editing the Χ1 field and not accidentally reusing a Ψ or Μ pattern of a different length."],"exampleFix":"// before (wrong length / wrong alphabet)\nlugx1 = \"x.x.x.x\";                       // too short\nlugx1 = \"1x0...\".padEnd(41, \".\");        // illegal digits\n\n// after — exactly 41 chars of . x X\nlugx1 = \".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..\";","handlingStrategy":"validation","validationCode":"const CHI1_LEN = 41;\nconst lugRe = /^[.xX]*$/;\nfunction validChi1(lugx1) {\n  return typeof lugx1 === 'string' && lugx1.length === CHI1_LEN && lugRe.test(lugx1);\n}\n// call before running Lorenz with pattern='Custom'\nif (!validChi1(args[26])) throw new Error('Χ1 lugs must be 41 chars of . x X');","typeGuard":"function isChi1Lugs(v): v is string {\n  return typeof v === 'string' && v.length === 41 && /^[.xX]*$/.test(v);\n}","tryCatchPattern":null,"preventionTips":["Keep a single source of truth for each wheel's expected length (41 for Χ1) and assert against it.","Normalise lug strings to '.' and 'x' only, then verify length before running.","When using 'Custom', pre-validate all twelve lug fields in one pass rather than relying on sequential errors."],"tags":["lorenz","cipher","validation","input-length","wheel-pattern"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}