gchq/CyberChef · error · TypeError
Recipe can only contain function names or functions
Error message
Recipe can only contain function names or functions
What it means
Thrown by NodeRecipe._validateIngredient as the final fallback when the ingredient is neither a string (op name), nor a function (operation class), nor an object with an 'op' property. It is the catch-all for structurally invalid recipe entries.
Source
Thrown at src/node/NodeRecipe.mjs:64
} 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
*/
_parseConfig(recipeConfig) {
if (!recipeConfig) {
this.opList = [];
return;
}
if (!Array.isArray(recipeConfig)) {
recipeConfig = [recipeConfig];
}
View on GitHub (pinned to 4290ea7539)
Solutions
- Use one of the supported shapes: an operation name string, an operation function, or {op: "<name>", args: [...]} with the 'op' key (not 'operation'/'name').
- Remove null/undefined/empty entries before building the recipe.
- Validate each entry's shape before passing the array to chef.bake.
Example fix
// before: wrong key
chef.bake(input, [{operation:"From Hex", args:["None"]}]);
// after
chef.bake(input, [{op:"From Hex", args:["None"]}]); Defensive patterns
Strategy: type-guard
Validate before calling
function isValidIngredient(ing) {
return typeof ing === "string" || typeof ing === "function" || (ing && typeof ing === "object" && "op" in ing);
}
function assertRecipeShape(recipe) {
for (const ing of recipe) if (!isValidIngredient(ing)) throw new Error("Recipe entry must be a name, function, or {op, args?}");
} Type guard
const isRecipeEntry = (ing) => typeof ing === "string" || typeof ing === "function" || (ing != null && typeof ing === "object" && Object.prototype.hasOwnProperty.call(ing, "op"));
Try / catch
try { chef.bake(input, recipe); } catch (e) { if (e instanceof TypeError && /only contain function names or functions/.test(e.message)) { /* fix entry shape to {op, args?} */ } else throw e; } Prevention
- Use only supported shapes: string | function | {op, args?} (key is 'op', not 'operation'/'name').
- Filter out null/undefined/array entries when building recipes dynamically.
- Validate the schema before calling chef.bake.
When it happens
Trigger: A recipe array contains a number, boolean, null, array, or an object without an 'op' key. Example: [{operation: "From Hex"}] (wrong key — must be 'op') or [42].
Common situations: Wrong recipe schema (using 'operation'/'name' instead of 'op'); passing a nested array; nulls from optional-chaining bugs when building the recipe dynamically.
Related errors
- Couldn't find an operation with name '${ing}'.
- flowControl operations like ${ing.opName} are not currently
- Inputted function not a Chef operation.
- 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/26ef4267db3fe62e.
Report an issue: GitHub.