gchq/CyberChef · error · Error
Invalid recipe
Error message
Invalid recipe
What it means
Thrown by Utils._validatePrettyRecipe() (line 1056), the structural pre-check for the bespoke 'pretty' recipe format (Op_name(args)/disabled). Fires when indexOf('(') returns -1 (no opening paren anywhere from position i) OR when the next '(' sits exactly at position i (no operation name before the paren). Reached only for non-JSON recipes (strings not starting with '[').
Source
Thrown at src/core/Utils.mjs:1056
recipeConfig.push(op);
}
return recipeConfig;
}
/**
* Performs a linear structural validation pass over pretty recipe syntax.
*
* @param {string} recipe
* @throws {Error} if the recipe is structurally invalid
*/
static _validatePrettyRecipe(recipe) {
let i = 0;
while (i < recipe.length) {
const openParen = recipe.indexOf("(", i);
if (openParen === -1 || openParen === i) {
throw new Error("Invalid recipe");
}
i = openParen + 1;
let inString = false,
escaped = false,
foundCloseParen = false;
for (; i < recipe.length; i++) {
const c = recipe[i];
if (inString) {
if (escaped) {
escaped = false;
} else if (c === "\\") {
escaped = true;
} else if (c === "'") {
inString = false;
}View on GitHub (pinned to 4290ea7539)
Solutions
- Ensure every operation in the pretty recipe is written as Op_name(args), even if args are empty: 'From Base64()'.
- Remove trailing free text after the last operation, or wrap it as an operation.
- If you have JSON, pass it through as JSON (it starts with '[' and skips this validator).
Example fix
// before
Utils.parseRecipeConfig('From Base64'); // no parens
// after
Utils.parseRecipeConfig('From Base64()');
// or pass JSON
Utils.parseRecipeConfig('[{"op":"From Base64","args":[]}]'); Defensive patterns
Strategy: validation
Validate before calling
function looksLikePrettyRecipe(s) {
const trimmed = s.trim();
if (trimmed.startsWith('[')) return false; // JSON
return /\(/.test(trimmed) && /^\S/.test(trimmed); // has a paren and a name before it
} Type guard
null
Try / catch
try { Utils.parseRecipeConfig(recipeStr); } catch (e) {
if (/Invalid recipe/.test(e.message) && !recipeStr.includes('(')) { /* missing parens */ }
} Prevention
- Write every pretty-recipe operation as Op_name(), even with empty args.
- Strip trailing free text after the last operation.
- Prefer the JSON recipe form (starts with '[') for programmatic use.
When it happens
Trigger: A pretty recipe string with no parentheses at all (e.g. 'Some Operation' with no args/parens); trailing text after a valid op that contains no '(' (the while loop's next iteration finds none); a recipe beginning with '(' so the op name before it is empty.
Common situations: Pasting free text or an operation name without its argument list; a multiline pretty recipe where a line was stripped of its parentheses; concatenating recipe fragments incorrectly so a trailing fragment lacks parens.
Related errors
- Failed to hydrate operation '${o.name}': ${err}
- Invalid marker while parsing JPEG at pos ${stream.position}:
- Unable to parse JPEG successfully
- Invalid block type while parsing DEFLATE stream at pos ${str
- Invalid Huffman Code length while parsing DEFLATE block at p
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/ba891e1648c4d79b.
Report an issue: GitHub.