gchq/CyberChef · error · DishError
Data is not a valid ${Dish.enumLookup(type)}: ${sample}
Error message
Data is not a valid ${Dish.enumLookup(type)}: ${sample} What it means
Thrown by Dish.set(value, type) after the value and type are assigned, when this.valid() returns false. valid() is a runtime type-check that asserts the JS value matches the declared Dish enum: STRING/HTML require typeof 'string', NUMBER requires typeof 'number', ARRAY_BUFFER requires an ArrayBuffer instance, BIG_NUMBER requires a BigNumber (or its serialised {c,e,s} form), FILE requires a File, LIST_FILE requires an Array of Files, JSON always passes. The sample is a truncated JSON.stringify of the offending value.
Source
Thrown at src/core/Dish.mjs:180
* Sets the data value and type and then validates them.
*
* @param {*} value
* - The value of the input data.
* @param {number} type
* - The data type of value, see Dish enums.
*/
set(value, type) {
if (typeof type === "string") {
type = Dish.typeEnum(type);
}
log.debug("Dish type: " + Dish.enumLookup(type));
this.value = value;
this.type = type;
if (!this.valid()) {
const sample = Utils.truncate(JSON.stringify(this.value), 25);
throw new DishError(`Data is not a valid ${Dish.enumLookup(type)}: ${sample}`);
}
}
/**
* Returns the Dish as the given type, without mutating the original dish.
*
* If running in a browser, get is asynchronous.
*
* @Node
*
* @param {number} type - The data type of value, see Dish enums.
* @returns {Dish | Promise} - (Browser) A promise | (Node) value of dish in given type
*/
presentAs(type) {
const clone = this.clone();
return clone.get(type);
}
View on GitHub (pinned to 4290ea7539)
Solutions
- Inspect the sample in the message: it shows the actual value. Reconcile the value's JS type with the Dish type enum you passed.
- If the value is a string but the dish is NUMBER/ARRAY_BUFFER/FILE, convert it first (parseFloat, new Uint8Array, new File) before calling set.
- For File/ListFile/ArrayBuffer reconstructed after IPC or structuredClone, rebuild the typed object: new File([buf], name), buf.slice(0) for ArrayBuffer.
- For BigNumber received as {c,e,s}, valid() already auto-converts it - if conversion fails, the object shape was wrong; reconstruct with new BigNumber(...).
- Confirm the type argument: pass a Dish enum constant (Dish.STRING) or a string name handled by Dish.typeEnum; never an unrelated integer.
Example fix
// before
const dish = new Dish();
dish.set("42", Dish.NUMBER); // throws: string is not a number
// after
const dish = new Dish();
dish.set(parseFloat("42"), Dish.NUMBER); Defensive patterns
Strategy: type-guard
Validate before calling
function dishValueOk(value, typeEnum) {
switch (typeEnum) {
case 1: case 3: return typeof value === 'string'; // STRING, HTML
case 2: return typeof value === 'number' && !isNaN(value); // NUMBER
case 4: return value instanceof ArrayBuffer; // ARRAY_BUFFER
case 8: return typeof value === 'object' && value !== null; // JSON (always)
case 6: return typeof File !== 'undefined' && value instanceof File; // FILE
case 7: return Array.isArray(value) && value.every(f => f instanceof File); // LIST_FILE
default: return true; // BYTE_ARRAY/JSON etc.
}
}
// call before dish.set(value, typeEnum) Type guard
function isDishString(v): v is string { return typeof v === 'string'; }
function isDishNumber(v): v is number { return typeof v === 'number' && !isNaN(v); }
function isDishArrayBuffer(v): v is ArrayBuffer { return v instanceof ArrayBuffer; } Try / catch
try {
dish.set(value, type);
} catch (e) {
if (e instanceof DishError && /is not a valid/.test(e.message)) {
// value/type mismatch - reconcile before retrying
}
throw e;
} Prevention
- Always construct dish values with dish.set(), never by assigning dish.value directly.
- After IPC/structuredClone/postMessage, rebuild File/ArrayBuffer/BigNumber objects before set().
- Pass the Dish type as a Dish.* enum constant or a string name, never an ad-hoc integer.
When it happens
Trigger: Calling dish.set('hello', Dish.NUMBER) (string value for a number dish); dish.set({}, Dish.ARRAY_BUFFER) (plain object, not ArrayBuffer); dish.set([72,73], Dish.FILE) (byte array where a File is required); passing a serialised File object that lost its File prototype after structuredClone/postMessage into Dish.FILE.
Common situations: An operation's run() returns a runtime value whose JS type disagrees with its declared output dish; round-tripping dishes through WebWorkers or Node IPC where File/ArrayBuffer/BigNumber lose their prototype; BigNumber passed as a plain JSON object from an external source; mistyping the type argument (e.g. passing the string 'number' when an enum was expected - though typeEnum handles the string form, a wrong enum int slips through).
Related errors
- Error translating from ${Dish.enumLookup(this.type)} to Arra
- Error translating from ArrayBuffer to ${Dish.enumLookup(toTy
- ${this.name} cannot be empty.
- ${this.name} length cannot exceed ${this.maxLength}.
- ${this.name} must be a number.
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/de542db2ea9e9f9d.
Report an issue: GitHub.