{"record":{"id":"050ddd04b437e5a6","repo":"gchq/CyberChef","slug":"value-a-and-modulus-m-must-be-defined","errorCode":null,"errorMessage":"Value (a) and Modulus (m) must be defined","messagePattern":"Value \\(a\\) and Modulus \\(m\\) must be defined","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/ModularInverse.mjs","lineNumber":80,"sourceCode":"        let a, m;\n\n        if (aParam && mParam) {\n            // Case 1: value and modulus both given as parameters\n            a = aParam;\n            m = mParam;\n        } else if (!aParam && mParam) {\n            // Case 2: value missing - take from input\n            a = inputVal;\n            m = mParam;\n            if (!a) throw new OperationError(\"Value (a) must be defined\");\n        } else if (aParam && !mParam) {\n            // Case 3: modulus missing - take from input\n            a = aParam;\n            m = inputVal;\n            if (!m) throw new OperationError(\"Modulus (m) must be defined\");\n        } else if (!aParam && !mParam) {\n            // Case 4: value and modulus both missing\n            throw new OperationError(\"Value (a) and Modulus (m) must be defined\");\n        }\n\n        const aBI = parseBigInt(a, \"Value (a)\");\n        const mBI = parseBigInt(m, \"Modulus (m)\");\n\n        if (mBI <= 0n) {\n            throw new OperationError(\"Modulus must be greater than zero\");\n        }\n\n        const aNorm = ((aBI % mBI) + mBI) % mBI;\n        const [g, x] = egcd(aNorm, mBI);\n\n        if (g !== 1n && g !== -1n) {\n            throw new OperationError(\"Inverse does not exist because gcd(a, m) ≠ 1\");\n        }\n\n        let inv = x;\n        if (g === -1n) inv = -inv;","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/ModularInverse.mjs#L62-L98","documentation":"Thrown by Modular Inverse in Case 4: both the Value (a) and Modulus (m) arguments are blank. The operation has nowhere to source either operand (Input is not consulted in this branch), so it fails fast rather than proceeding with undefined values.","triggerScenarios":"run(input, args) with args[0] and args[1] both empty/whitespace, regardless of the Input content. Note Input is ignored entirely when both arguments are blank — supplying input here will NOT satisfy the check.","commonSituations":"Default recipe where both fields ship empty; user assumes Input populates both operands simultaneously; cleared both boxes to 'start fresh' and ran without refilling.","solutions":["Populate the Value (a) argument (and let Modulus come from Input), or populate both arguments.","Remember Input fills at most one blank field — it cannot supply both operands.","Restore the default recipe or fill both argument boxes explicitly."],"exampleFix":"// before: both args empty\nchef.bake(\"Modular Inverse\", [\"\", \"\"], \"3\");  // still errors\n// after\nchef.bake(\"Modular Inverse\", [\"3\", \"7\"], \"\");","handlingStrategy":"validation","validationCode":"const aParam = (args[0] ?? \"\").trim();\nconst mParam = (args[1] ?? \"\").trim();\nif (!aParam && !mParam) {\n  // both blank — fill at least Value (Input will not cover both)\n}","typeGuard":"const hasEitherArg = (aStr, mStr) =>\n  Boolean((aStr ?? \"\").trim()) || Boolean((mStr ?? \"\").trim());","tryCatchPattern":"try { chef.bake(\"Modular Inverse\", [\"\", \"\"], input); }\ncatch (e) { if (e.message.includes(\"Value (a) and Modulus (m)\")) fillArgs(); else throw e; }","preventionTips":["Never leave both Value and Modulus blank — Input cannot fill both.","Restore defaults if unsure.","Populate arguments explicitly in programmatic recipes."],"tags":["crypto","modular-arithmetic","argument-validation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}