{"record":{"id":"6a37f2a14836fda8","repo":"gchq/CyberChef","slug":"invalid-ingredient-value-not-a-number-sample","errorCode":null,"errorMessage":"Invalid ingredient value. Not a number: ${sample}","messagePattern":"Invalid ingredient value\\. Not a number: (.+?)","errorType":"validation","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/Ingredient.mjs","lineNumber":237,"sourceCode":"        switch (type) {\n            case \"binaryString\":\n            case \"binaryShortString\":\n            case \"editableOption\":\n            case \"editableOptionShort\":\n                return Utils.parseEscapedChars(data);\n            case \"byteArray\":\n                if (typeof data == \"string\") {\n                    data = data.replace(/\\s+/g, \"\");\n                    return fromHex(data);\n                } else {\n                    return data;\n                }\n            case \"number\":\n                if (data === null) return data;\n                number = parseFloat(data);\n                if (isNaN(number)) {\n                    const sample = Utils.truncate(data.toString(), 10);\n                    throw new OperationError(\n                        \"Invalid ingredient value. Not a number: \" + sample,\n                    );\n                }\n                return number;\n            default:\n                return data;\n        }\n    }\n\n}\n\nexport default Ingredient;\n","sourceCodeStart":219,"sourceCodeEnd":250,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/Ingredient.mjs#L219-L250","documentation":"Thrown by Ingredient.prepare() (line 237) when the ingredient type is 'number', data is not null, and parseFloat(data) returns NaN. prepare() runs inside the Ingredient value setter, so this fires DURING assignment of ingValues - earlier than the validate() number check (error 7). The sample is the truncated raw input.","triggerScenarios":"Setting ingredient.value = 'abc' on a number ingredient (parseFloat('abc') is NaN); passing a non-numeric string where a number is expected via op.ingValues; an object/symbol coerced to a non-numeric string.","commonSituations":"Recipe supplies a text value for a numeric arg; UI sends a raw textfield string into a number ingredient without client-side parsing; programmatic recipe build using an untrimmed/non-numeric string.","solutions":["Pass a value parseFloat can handle (a numeric string like '16' or a number).","Parse and validate the source text yourself before assigning to ingValues.","Provide a numeric defaultValue so empty input falls back gracefully."],"exampleFix":"// before\nop.ingValues = ['abc']; // number ingredient\n\n// after\nop.ingValues = ['16']; // or the number 16","handlingStrategy":"validation","validationCode":"function prepareNumberArg(data) {\n  if (data == null) return data;\n  const n = parseFloat(data);\n  if (isNaN(n)) throw new Error(`Not a number: ${String(data).slice(0, 10)}`);\n  return n;\n}\n// call before op.ingValues = [rawText]","typeGuard":"function isParsableNumber(v): v is string { return v != null && !isNaN(parseFloat(v)); }","tryCatchPattern":"try { op.ingValues = [rawText]; } catch (e) {\n  if (e instanceof OperationError && /Not a number/.test(e.message)) { /* rawText unparseable */ }\n}","preventionTips":["Parse numeric text with parseFloat and check isNaN before assigning to a number ingredient.","Keep number ingredients supplied as numbers, not free text.","Trim whitespace before parsing."],"tags":["ingredient","number","coercion","operationerror"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}