gchq/CyberChef · error · OperationError

Χ1 custom lugs must be 41 long and can only include . or x

Error message

Χ1 custom lugs must be 41 long and can only include . or x

What it means

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.

Source

Thrown at src/core/operations/Lorenz.mjs:289

        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);
            chosenSetting.X[5] = this.readLugs(lugx5);
        } else {

View on GitHub (pinned to 4290ea7539)

Solutions

  1. 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).
  2. 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'.
  3. Verify length and alphabet programmatically before invoking the operation (see validationCode).
  4. Double-check you are editing the Χ1 field and not accidentally reusing a Ψ or Μ pattern of a different length.

Example fix

// before (wrong length / wrong alphabet)
lugx1 = "x.x.x.x";                       // too short
lugx1 = "1x0...".padEnd(41, ".");        // illegal digits

// after — exactly 41 chars of . x X
lugx1 = ".x...xxx.x.xxxx.x...x.x..xxx....xx.xxxx..";
Defensive patterns

Strategy: validation

Validate before calling

const CHI1_LEN = 41;
const lugRe = /^[.xX]*$/;
function validChi1(lugx1) {
  return typeof lugx1 === 'string' && lugx1.length === CHI1_LEN && lugRe.test(lugx1);
}
// call before running Lorenz with pattern='Custom'
if (!validChi1(args[26])) throw new Error('Χ1 lugs must be 41 chars of . x X');

Type guard

function isChi1Lugs(v): v is string {
  return typeof v === 'string' && v.length === 41 && /^[.xX]*$/.test(v);
}

Prevention

When it happens

Trigger: 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().

Common situations: 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.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/f8a4efbeac6feb29. Report an issue: GitHub.