{"record":{"id":"de542db2ea9e9f9d","repo":"gchq/CyberChef","slug":"data-is-not-a-valid-dish-enumlookup-type-sa","errorCode":null,"errorMessage":"Data is not a valid ${Dish.enumLookup(type)}: ${sample}","messagePattern":"Data is not a valid (.+?): (.+?)","errorType":"validation","errorClass":"DishError","httpStatus":null,"severity":"error","filePath":"src/core/Dish.mjs","lineNumber":180,"sourceCode":"     * Sets the data value and type and then validates them.\n     *\n     * @param {*} value\n     *     - The value of the input data.\n     * @param {number} type\n     *     - The data type of value, see Dish enums.\n     */\n    set(value, type) {\n        if (typeof type === \"string\") {\n            type = Dish.typeEnum(type);\n        }\n\n        log.debug(\"Dish type: \" + Dish.enumLookup(type));\n        this.value = value;\n        this.type = type;\n\n        if (!this.valid()) {\n            const sample = Utils.truncate(JSON.stringify(this.value), 25);\n            throw new DishError(`Data is not a valid ${Dish.enumLookup(type)}: ${sample}`);\n        }\n    }\n\n    /**\n     * Returns the Dish as the given type, without mutating the original dish.\n     *\n     * If running in a browser, get is asynchronous.\n     *\n     * @Node\n     *\n     * @param {number} type - The data type of value, see Dish enums.\n     * @returns {Dish | Promise} - (Browser) A promise | (Node) value of dish in given type\n     */\n    presentAs(type) {\n        const clone = this.clone();\n        return clone.get(type);\n    }\n","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/Dish.mjs#L162-L198","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before\nconst dish = new Dish();\ndish.set(\"42\", Dish.NUMBER); // throws: string is not a number\n\n// after\nconst dish = new Dish();\ndish.set(parseFloat(\"42\"), Dish.NUMBER);","handlingStrategy":"type-guard","validationCode":"function dishValueOk(value, typeEnum) {\n  switch (typeEnum) {\n    case 1: case 3: return typeof value === 'string';        // STRING, HTML\n    case 2: return typeof value === 'number' && !isNaN(value); // NUMBER\n    case 4: return value instanceof ArrayBuffer;               // ARRAY_BUFFER\n    case 8: return typeof value === 'object' && value !== null; // JSON (always)\n    case 6: return typeof File !== 'undefined' && value instanceof File; // FILE\n    case 7: return Array.isArray(value) && value.every(f => f instanceof File); // LIST_FILE\n    default: return true; // BYTE_ARRAY/JSON etc.\n  }\n}\n// call before dish.set(value, typeEnum)","typeGuard":"function isDishString(v): v is string { return typeof v === 'string'; }\nfunction isDishNumber(v): v is number { return typeof v === 'number' && !isNaN(v); }\nfunction isDishArrayBuffer(v): v is ArrayBuffer { return v instanceof ArrayBuffer; }","tryCatchPattern":"try {\n  dish.set(value, type);\n} catch (e) {\n  if (e instanceof DishError && /is not a valid/.test(e.message)) {\n    // value/type mismatch - reconcile before retrying\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["dish","type-mismatch","validation","disherror"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}