{"record":{"id":"2dfd3e9a4ca23998","repo":"gchq/CyberChef","slug":"a-minimum-of-one-reflector-must-be-supplied","errorCode":null,"errorMessage":"A minimum of one reflector must be supplied","messagePattern":"A minimum of one reflector must be supplied","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/MultipleBombe.mjs","lineNumber":214,"sourceCode":"        }\n        if (rotors.length < 3) {\n            throw new OperationError(\"A minimum of three rotors must be supplied\");\n        }\n        if (fourthRotorsStr !== \"\") {\n            for (let rstr of fourthRotorsStr.split(\"\\n\")) {\n                rstr = this.validateRotor(rstr);\n                fourthRotors.push(rstr);\n            }\n        }\n        if (fourthRotors.length === 0) {\n            fourthRotors.push(\"\");\n        }\n        for (const rstr of reflectorsStr.split(\"\\n\")) {\n            const reflector = new Reflector(rstr);\n            reflectors.push(reflector);\n        }\n        if (reflectors.length === 0) {\n            throw new OperationError(\"A minimum of one reflector must be supplied\");\n        }\n        if (crib.length === 0) {\n            throw new OperationError(\"Crib cannot be empty\");\n        }\n        if (offset < 0) {\n            throw new OperationError(\"Offset cannot be negative\");\n        }\n        // For symmetry with the Enigma op, for the input we'll just remove all invalid characters\n        input = input.replace(/[^A-Za-z]/g, \"\").toUpperCase();\n        crib = crib.replace(/[^A-Za-z]/g, \"\").toUpperCase();\n        const ciphertext = input.slice(offset);\n        let update;\n        if (isWorkerEnvironment()) {\n            update = this.updateStatus;\n        } else {\n            update = undefined;\n        }\n        let bombe = undefined;","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/MultipleBombe.mjs#L196-L232","documentation":"Thrown by MultipleBombe.run when the reflectors list ends up empty after splitting args[3] on newlines. At least one reflector is required because the Bombe loops over reflector choices. In practice this branch is hard to reach because even an empty string splits to [''] and the loop constructs one Reflector.","triggerScenarios":"run(input, args) where reflectors.length === 0 after the split/construct loop. Realistically reachable only if args[3] is something that produces no iterations (e.g. the reflector string is manipulated to yield an array that the for..of skips), since ''.split('\\n') returns [''] and the loop runs once.","commonSituations":"Recipe where the reflectors field was set to null/undefined rather than a string; programmatic invocation passing a non-string reflectors argument; edge cases where a Reflector constructor throws and is caught upstream leaving the array empty (not the case in this code).","solutions":["Provide at least one reflector wiring string (e.g. the standard B reflector 'YRUHQSLDPXNGOKMIEBFZCWVJAT').","Ensure the reflectors argument is a string, never null or undefined.","Restore default reflector values if the field was cleared."],"exampleFix":"// before\nchef.bake(\"Multiple Bombe\", [..., reflectors=\"\", ...]);\n// after\nchef.bake(\"Multiple Bombe\", [..., reflectors=\"YRUHQSLDPXNGOKMIEBFZCWVJAT\", ...]);","handlingStrategy":"validation","validationCode":"const reflectorsStr = args[3];\nif (typeof reflectorsStr !== \"string\" || reflectorsStr.split(\"\\n\").length === 0) {\n  // supply a reflector string\n}","typeGuard":"const hasReflector = (s) => typeof s === \"string\" && s.length > 0;","tryCatchPattern":"try { chef.bake(\"Multiple Bombe\", args); }\ncatch (e) { if (e.message === \"A minimum of one reflector must be supplied\") addReflector(); else throw e; }","preventionTips":["Always include at least the B reflector.","Ensure reflectors arg is a non-empty string, never null.","Restore defaults if the field was cleared."],"tags":["crypto","enigma","bombe","validation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}