gchq/CyberChef · error · OperationError
${this.name} must be one of the following: ${permittedOption
Error message
${this.name} must be one of the following: ${permittedOptions.join(", ")}. What it means
Thrown by Ingredient.validate() option checks (line 153) when type is 'option', defaultValue is an Array, and after lowercasing, checkVal matches none of the permitted options. Permitted options are defaultValue entries that are strings AND do not match the placeholder regex /^[/?[a-z0-9 -()^]+]$/i (bracketed placeholders like [Alpha] are excluded). Matching is case-insensitive.
Source
Thrown at src/core/Ingredient.mjs:153
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);
});
const valStr = (checkVal !== null && checkVal !== undefined) ? String(checkVal).toLowerCase() : "";
const matchedOption = permittedOptions.find(opt => opt.toLowerCase() === valStr);
if (!matchedOption) {
throw new OperationError(`${this.name} must be one of the following: ${permittedOptions.join(", ")}.`);
}
}
}
// 5. argSelector checks
if (this.type === "argSelector") {
if (Array.isArray(this.defaultValue)) {
const permittedOptions = this.defaultValue
.map(opt => opt.name)
.filter(optName => {
if (typeof optName !== "string") return false;
return !optName.match(/^\[\/?[a-z0-9 -()^]+\]$/i);
});
const valStr = (checkVal !== null && checkVal !== undefined) ? String(checkVal).toLowerCase() : "";
const matchedOption = permittedOptions.find(opt => opt.toLowerCase() === valStr);
if (!matchedOption) {
throw new OperationError(`${this.name} must be one of the following: ${permittedOptions.join(", ")}.`);
}View on GitHub (pinned to 4290ea7539)
Solutions
- Set the ingredient to one of the values listed in the error message (case-insensitive).
- If the operation's options changed, update the recipe to a currently-valid option.
- Confirm defaultValue in the operation config actually lists real options, not only bracketed placeholders.
Example fix
// before - permitted: CBC, ECB op.ingValues = ['CFB']; // after op.ingValues = ['CBC'];
Defensive patterns
Strategy: validation
Validate before calling
const permitted = defaultValue.filter(o => typeof o === 'string' && !/^[/?[a-z0-9 -()^]+]$/i.test(o));
if (!permitted.some(o => o.toLowerCase() === String(val).toLowerCase())) {
throw new Error(`${name} not in ${permitted.join(', ')}`);
} Type guard
function isValidOption(v, permitted): v is string { return typeof v === 'string' && permitted.some(o => o.toLowerCase() === v.toLowerCase()); } Try / catch
try { op.ingValues = [val]; } catch (e) { if (/must be one of the following/.test(e.message)) { val = permitted[0]; } } Prevention
- Pull option lists from the current operation version, not a cached recipe.
- Use exact option strings; matching is case-insensitive but spelling must match.
- Avoid recipes that reference removed/renamed options.
When it happens
Trigger: An option ingredient (dropdown) receives a value that is not one of its declared options; e.g. a 'Mode' option with permitted ['CBC','ECB'] gets 'CFB'; or the only entries are bracketed placeholders so permittedOptions is empty and nothing matches.
Common situations: Recipe references an option value renamed or removed in a newer operation version; typo in the option value; locale/case mismatch; copying an option arg from a different operation.
Related errors
- ${this.name} cannot be empty.
- ${this.name} length cannot exceed ${this.maxLength}.
- ${this.name} must be a number.
- ${this.name} must be an integer.
- ${this.name} must be greater than or equal to ${this.min}.
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/51735f7f6922eb34.
Report an issue: GitHub.