gchq/CyberChef · error · OperationError
${this.name} must be a number.
Error message
${this.name} must be a number. What it means
Thrown by Ingredient.validate() number checks (line 130) when the ingredient type is 'number' and checkVal is null, undefined, or NaN. This runs AFTER Ingredient.prepare() has already coerced the raw value, so by this point the value could not be parsed into a finite number.
Source
Thrown at src/core/Ingredient.mjs:130
}
// 2. maxLength check
if (typeof this.maxLength === "number" && checkVal !== null && checkVal !== undefined) {
if (typeof checkVal === "string" && checkVal.length > this.maxLength) {
throw new OperationError(`${this.name} length cannot exceed ${this.maxLength}.`);
}
if (Array.isArray(checkVal) && checkVal.length > this.maxLength) {
throw new OperationError(`${this.name} length cannot exceed ${this.maxLength}.`);
}
if (checkVal instanceof Uint8Array && checkVal.length > this.maxLength) {
throw new OperationError(`${this.name} length cannot exceed ${this.maxLength}.`);
}
}
// 3. number checks
if (this.type === "number") {
if (checkVal === null || checkVal === undefined || isNaN(checkVal)) {
throw new OperationError(`${this.name} must be a number.`);
}
if (this.integer && !Number.isInteger(checkVal)) {
throw new OperationError(`${this.name} must be an integer.`);
}
if (typeof this.min === "number" && checkVal < this.min) {
throw new OperationError(`${this.name} must be greater than or equal to ${this.min}.`);
}
if (typeof this.max === "number" && checkVal > this.max) {
throw new OperationError(`${this.name} must be less than or equal to ${this.max}.`);
}
}
// 4. option checks
if (this.type === "option") {
if (Array.isArray(this.defaultValue)) {
const permittedOptions = this.defaultValue.filter(opt => {
if (typeof opt !== "string") return false;
return !opt.match(/^\[\/?[a-z0-9 -()^]+\]$/i);View on GitHub (pinned to 4290ea7539)
Solutions
- Supply a numeric value for the ingredient in the recipe/args.
- Ensure the ingredient config declares a numeric defaultValue so null/undefined fall back to it.
- If the value comes from user text, parse it (parseFloat) before it reaches the ingredient.
Example fix
// before
op.ingValues = [null]; // number ingredient, no default
// after
op.ingValues = [16];
// or in config: { name:'Rounds', type:'number', value: 16 } Defensive patterns
Strategy: validation
Validate before calling
function ensureNumber(name, val) {
if (val == null || (typeof val === 'number' && isNaN(val))) {
throw new Error(`${name} must be a number`);
}
} Type guard
function isFiniteNumber(v): v is number { return typeof v === 'number' && !isNaN(v); } Try / catch
try { op.ingValues = [val]; } catch (e) { if (/must be a number/.test(e.message)) { val = defaultNumber; } } Prevention
- Always supply a numeric value or a numeric defaultValue for number ingredients.
- Parse user text with parseFloat and check isNaN before building ingValues.
- Provide numeric defaults in ingredient configs.
When it happens
Trigger: A number-typed ingredient receives null/undefined (and has no numeric default), or prepare() left it as NaN because the raw string was non-numeric and somehow reached validate (normally prepare throws first - see error 13).
Common situations: A recipe omits a required numeric arg (rounds, length, offset) and the ingredient has no default; an operation that previously had a numeric default loses it after a config edit.
Related errors
- ${this.name} must be an integer.
- ${this.name} must be greater than or equal to ${this.min}.
- ${this.name} must be less than or equal to ${this.max}.
- ${this.name} cannot be empty.
- ${this.name} length cannot exceed ${this.maxLength}.
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/d9a5cb56154ef1f9.
Report an issue: GitHub.