gchq/CyberChef · error · Error
Failed to hydrate operation '${o.name}': ${err}
Error message
Failed to hydrate operation '${o.name}': ${err} What it means
Thrown by Recipe._hydrateOpList() (line 80) wrapping any exception from constructing an operation instance (new modules[o.module][o.name]()) or from assigning op.ingValues. Notably this throws a plain Error, NOT OperationError. The most common inner cause is operation-not-found: modules[o.module][o.name] is undefined when the recipe references an op name/module that does not exist, so calling it as a constructor throws TypeError. The second cause is an ingValues failure (error 14) wrapped again here.
Source
Thrown at src/core/Recipe.mjs:80
if (!modules) {
// Using Webpack Magic Comments to force the dynamic import to be included in the main chunk
// https://webpack.js.org/api/module-methods/
modules = await import(/* webpackMode: "eager" */ "./config/modules/OpModules.mjs");
modules = modules.default;
}
this.opList = this.opList.map(o => {
if (o instanceof Operation) {
return o;
} else {
try {
const op = new modules[o.module][o.name]();
op.ingValues = o.ingValues;
op.breakpoint = o.breakpoint;
op.disabled = o.disabled;
return op;
} catch (err) {
throw new Error(`Failed to hydrate operation '${o.name}': ${err}`);
}
}
});
}
/**
* Returns the value of the Recipe as it should be displayed in a recipe config.
*
* @returns {Object[]}
*/
get config() {
return this.opList.map(op => ({
op: op.name,
args: op.ingValues,
}));
}
View on GitHub (pinned to 4290ea7539)
Solutions
- Read the inner ${err}: 'modules[...][...] is not a constructor' / 'undefined is not a constructor' means the op name or module is wrong - verify against the current operation catalogue.
- Operation names in recipes use spaces, not underscores; confirm spelling and capitalisation.
- If the inner error is an OperationError about an ingredient, fix that arg (see error 14).
- Ensure any custom operation is registered in the module tree before hydrating the recipe.
Example fix
// before - wrong op name
recipe = [{ op: 'From_Base64', args: [], module: 'Default' }];
// after
recipe = [{ op: 'From Base64', args: [], module: 'Default' }]; Defensive patterns
Strategy: validation
Validate before calling
import OperationList from './core/config/OperationList.mjs';
const known = new Set(OperationList.map(o => o.op));
function validateRecipeOps(recipe) {
for (const r of recipe) if (!known.has(r.op)) throw new Error(`Unknown op: ${r.op}`);
} Type guard
function opExists(name, modules): boolean { return !!(modules && modules.Default && typeof modules.Default[name] === 'function'); } Try / catch
try { await recipe._hydrateOpList(); } catch (e) {
if (/Failed to hydrate operation/.test(e.message)) { /* name/module wrong or arg invalid */ }
} Prevention
- Use the exact current operation display name (spaces, not underscores).
- Validate recipe op names against OperationList before hydration.
- Re-save recipes after upgrading CyberChef versions.
When it happens
Trigger: A recipe entry references an operation name that was renamed/removed (e.g. 'From_Base64' vs 'From Base64'); the module key is wrong or missing; the operation exists but one of its args is invalid, so op.ingValues = o.ingValues throws error 14 which gets wrapped here.
Common situations: Loading a recipe saved against an older or newer CyberChef version where an operation was renamed; hand-written recipe JSON with a typo in the op name or module; recipe references a custom operation whose module was not registered.
Related errors
- Invalid recipe
- Failed to set value of ingredient '${this._ingList[i].name}'
- Error: Invalid output format
- Unrecognized capitalization scope
- Rotor ${i} must be provided.
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/d252d70e0c237981.
Report an issue: GitHub.