gchq/CyberChef · error · TypeError
Inputted function not a Chef operation.
Error message
Inputted function not a Chef operation.
What it means
Thrown by NodeRecipe._validateIngredient when the ingredient is a function that is not flowControl but is not present in the registered operations list. It distinguishes 'wrong kind of function' from 'unknown name' (714) and 'flowControl' (715).
Source
Thrown at src/node/NodeRecipe.mjs:54
const op = operations.find((op) => {
return sanitise(op.opName) === sanitise(ing);
});
if (op) {
// Need to validate against case 2
return this._validateIngredient(op);
} else {
throw new TypeError(`Couldn't find an operation with name '${ing}'.`);
}
// CASE operation given. Check its a chef operation and check its not flowcontrol
} else if (typeof ing === "function") {
if (ing.flowControl) {
throw new TypeError(`flowControl operations like ${ing.opName} are not currently allowed in recipes for chef.bake in the Node API`);
}
if (operations.includes(ing)) {
return ing;
} else {
throw new TypeError("Inputted function not a Chef operation.");
}
// CASE: op, maybe with configuration
} else if (ing.op) {
const sanitisedOp = this._validateIngredient(ing.op);
if (ing.args) {
return {op: sanitisedOp, args: ing.args};
}
return sanitisedOp;
} else {
throw new TypeError("Recipe can only contain function names or functions");
}
}
/**
* Parse an opList from a recipeConfig and assign it to the recipe's opList.
* @param {String | Function | String[] | Function[] | [String | Function]} recipeConfig
*/View on GitHub (pinned to 4290ea7539)
Solutions
- Pass operations by their canonical string name (handled by case 714's lookup) rather than as function references.
- Ensure the operation you import is the same module instance the Node API uses (same node_modules/CyberChef).
- Don't put arbitrary functions in a Node recipe — the API only accepts Chef operations or their names.
Example fix
// before: imported op is a different instance than the API's
import {FromHex} from "cyberchef/src/...";
chef.bake(input, [FromHex]);
// after: reference by name
chef.bake(input, ["From Hex"]); Defensive patterns
Strategy: type-guard
Validate before calling
import { operations } from "cyberchef/src/node/index.mjs";
function assertOpsRegistered(recipe) {
for (const ing of recipe) if (typeof ing === "function" && !ing.flowControl && !operations.includes(ing))
throw new Error("Function is not a registered Chef operation; pass by name instead.");
} Type guard
const isChefOperation = (ing) => typeof ing === "function" && operations.includes(ing);
Try / catch
try { chef.bake(input, recipe); } catch (e) { if (e instanceof TypeError && /not a Chef operation/.test(e.message)) { /* pass op by name string */ } else throw e; } Prevention
- Reference operations by canonical name string in Node recipes.
- Avoid importing operation classes from a second CyberChef module instance.
- Don't place arbitrary functions in recipes.
When it happens
Trigger: A plain JS function, or an operation class from a different CyberChef build/fork, is passed in the recipe array. operations.includes(ing) is a reference check, so an operation imported from a mismatched version is a different object and fails the includes test.
Common situations: Importing an operation class from source while the Node API bundled its own copy (two module instances); passing a custom function thinking it will be invoked; mixing built recipe JSON with freshly imported classes.
Related errors
- Couldn't find an operation with name '${ing}'.
- flowControl operations like ${ing.opName} are not currently
- Recipe can only contain function names or functions
- Sorry, the ${name} operation is not available in the Node.js
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/eb57884b2931439c.
Report an issue: GitHub.