{"record":{"id":"d3e8d33c4ef90cea","repo":"gchq/CyberChef","slug":"flowcontrol-operations-like-ing-opname-are-not","errorCode":null,"errorMessage":"flowControl operations like ${ing.opName} are not currently allowed in recipes for chef.bake in the Node API","messagePattern":"flowControl operations like (.+?) are not currently allowed in recipes for chef\\.bake in the Node API","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/node/NodeRecipe.mjs","lineNumber":48,"sourceCode":"     *  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            }\n            return sanitisedOp;\n        } else {\n            throw new TypeError(\"Recipe can only contain function names or functions\");\n        }\n    }","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/node/NodeRecipe.mjs#L30-L66","documentation":"Thrown by NodeRecipe._validateIngredient when the ingredient is a function (an operation class) but its flowControl flag is set. The Node API deliberately excludes flow-control operations (Fork, Magic, etc.) from chef.bake recipes because they manipulate the recipe graph itself, which the Node execution model does not support.","triggerScenarios":"A recipe includes a flowControl operation passed as a function reference (e.g. chef.operations.Fork or the imported operation class). The check is ing.flowControl === true at validation time.","commonSituations":"Porting a browser recipe that uses Fork/Magic/Register/Label to the Node API; importing operations directly from src and adding them to a recipe array.","solutions":["Remove the flowControl operation from the Node recipe.","Reimplement its effect with a script or a different sequence of supported operations.","For Magic-style detection, run candidate recipes yourself instead of using the Magic op."],"exampleFix":"// before\nchef.bake(input, [Fork, \"From Hex\"]); // Fork is flowControl\n// after\nchef.bake(input, [\"From Hex\"]);","handlingStrategy":"validation","validationCode":"function assertNoFlowControl(recipe) {\n  for (const ing of recipe) if (typeof ing === \"function\" && ing.flowControl) throw new Error(`${ing.opName} is flowControl and unsupported in Node`);\n}","typeGuard":"const isFlowControl = (ing) => typeof ing === \"function\" && ing.flowControl === true;","tryCatchPattern":"try { chef.bake(input, recipe); } catch (e) { if (e instanceof TypeError && /flowControl operations/.test(e.message)) { /* remove op */ } else throw e; }","preventionTips":["Do not include Fork/Magic/Register/Label in Node recipes.","Filter recipe builders to drop flowControl operations.","Reimplement the needed behaviour with supported operations."],"tags":["node-api","noderecipe","flow-control","unsupported-operation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}