{"record":{"id":"752d5a79ab17a5f6","repo":"gchq/CyberChef","slug":"couldn-t-find-an-operation-with-name-ing","errorCode":null,"errorMessage":"Couldn't find an operation with name '${ing}'.","messagePattern":"Couldn't find an operation with name '(.+?)'\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/node/NodeRecipe.mjs","lineNumber":43,"sourceCode":"\n    /**\n     * Validate an ingredient & coerce to operation if necessary.\n     * @param {String | Function | Object} ing\n     * @returns {Function || Object} The operation, or an object with the\n     *  operation and its arguments\n     * @throws {TypeError} If it cannot find the operation in chef's list of operations.\n     */\n    _validateIngredient(ing) {\n        // CASE operation name given. Find operation and validate\n        if (typeof ing === \"string\") {\n            const op = operations.find((op) => {\n                return sanitise(op.opName) === sanitise(ing);\n            });\n            if (op) {\n                // Need to validate against case 2\n                return this._validateIngredient(op);\n            } else {\n                throw new TypeError(`Couldn't find an operation with name '${ing}'.`);\n            }\n        // CASE operation given. Check its a chef operation and check its not flowcontrol\n        } else if (typeof ing === \"function\") {\n            if (ing.flowControl) {\n                throw new TypeError(`flowControl operations like ${ing.opName} are not currently allowed in recipes for chef.bake in the Node API`);\n            }\n\n            if (operations.includes(ing)) {\n                return ing;\n            } else {\n                throw new TypeError(\"Inputted function not a Chef operation.\");\n            }\n        // CASE: op, maybe with configuration\n        } else if (ing.op) {\n            const sanitisedOp = this._validateIngredient(ing.op);\n            if (ing.args) {\n                return {op: sanitisedOp, args: ing.args};\n            }","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/node/NodeRecipe.mjs#L25-L61","documentation":"Thrown by NodeRecipe._validateIngredient when the ingredient is a string that does not match any registered operation after case/whitespace sanitisation. This is a TypeError (not OperationError) because it indicates a malformed Node API recipe, not bad user data flowing through an operation.","triggerScenarios":"A recipe array passed to chef.bake (or new NodeRecipe) contains a string op name that no registered operation has. The match uses sanitise() on both sides, so casing/spacing are tolerant, but a genuinely unknown/misspelled/moved op still fails.","commonSituations":"Typo in the op name; using an operation that was renamed or removed in the installed CyberChef version; referencing an operation that is browser-only and excluded from the Node build (see error 718); version skew between the recipe author and the runtime.","solutions":["Check the exact operation name against the installed build's operation list (e.g. the UI or the exported operations).","Correct typos and spacing; note that sanitise tolerates case but the canonical name is safest.","Upgrade/downgrade CyberChef so the operation exists, or substitute an equivalent operation.","If the operation is excluded from Node, replace it with a Node-supported alternative."],"exampleFix":"// before\nchef.bake(input, [{op:\"From Base 64\", args:[...]}]); // wrong name\n// after\nchef.bake(input, [{op:\"From Base64\", args:[...]}]);","handlingStrategy":"validation","validationCode":"import { operations } from \"cyberchef/src/node/index.mjs\";\nimport { sanitise } from \"cyberchef/src/node/apiUtils.mjs\";\nfunction recipeHasKnownOps(recipe) {\n  for (const ing of recipe) {\n    const name = typeof ing === \"string\" ? ing : ing?.op;\n    if (typeof name === \"string\" && !operations.some(o => sanitise(o.opName) === sanitise(name)))\n      throw new Error(`Unknown operation: ${name}`);\n  }\n}","typeGuard":"const isKnownOp = (name) => operations.some(o => sanitise(o.opName) === sanitise(name));","tryCatchPattern":"try { chef.bake(input, recipe); } catch (e) { if (e instanceof TypeError && /Couldn't find an operation/.test(e.message)) { /* correct/replace op name */ } else throw e; }","preventionTips":["Build recipes from the installed build's operation list.","Sanitise/normalise op names to the canonical spelling.","Catch TypeError specifically around chef.bake recipe construction."],"tags":["node-api","noderecipe","recipe-config","operation-not-found"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}