{"record":{"id":"b2dc987187443ca8","repo":"dotnet/runtime","slug":"value-was-not-an-integer","errorCode":null,"errorMessage":"value was not an integer","messagePattern":"value was not an integer","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mono/browser/runtime/memory.ts","lineNumber":152,"sourceCode":"\nexport function setI32_unchecked (offset: MemOffset, value: number): void {\n    receiveWorkerHeapViews();\n    Module.HEAP32[<any>offset >>> 2] = value;\n}\n\nexport function setI32 (offset: MemOffset, value: number): void {\n    assert_int_in_range(<any>value, -0x8000_0000, 0x7FFF_FFFF);\n    receiveWorkerHeapViews();\n    Module.HEAP32[<any>offset >>> 2] = value;\n}\n\nfunction autoThrowI52 (error: I52Error) {\n    if (error === I52Error.NONE)\n        return;\n\n    switch (error) {\n        case I52Error.NON_INTEGRAL:\n            throw new Error(\"value was not an integer\");\n        case I52Error.OUT_OF_RANGE:\n            throw new Error(\"value out of range\");\n        default:\n            throw new Error(\"unknown internal error\");\n    }\n}\n\n/**\n * Throws for values which are not 52 bit integer. See Number.isSafeInteger()\n */\nexport function setI52 (offset: MemOffset, value: number): void {\n    mono_check(Number.isSafeInteger(value), () => `Value is not a safe integer: ${value} (${typeof (value)})`);\n    receiveWorkerHeapViews();\n    const error = cwraps.mono_wasm_f64_to_i52(<any>offset, value);\n    autoThrowI52(error);\n}\n\n/**","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/mono/browser/runtime/memory.ts#L134-L170","documentation":"autoThrowI52 throws 'value was not an integer' when the native mono_wasm_f64_to_i52/u52 routine returns I52_ERROR_NON_INTEGRAL, meaning floor(value) != value. It is reached via setI52/setU52 (writing) and getI52/getU52 indirectly. These i52/u52 helpers store/load 52-bit integers in the wasm heap.","triggerScenarios":"Passing a fractional Number (e.g. 3.5) to setI52/setU52 or the exported setHeapI52/setHeapU52, or any path that converts a double to a 52-bit integer slot when the value is non-integral.","commonSituations":"Calling the low-level heap helpers (Module.setHeapI52/setHeapU52) with a computed float; feeding an unrounded measurement/index into a 52-bit slot; floating-point math drift producing x.0+epsilon.","solutions":["Round the value before passing: Math.trunc(value) or Math.round(value).","Validate with Number.isInteger(value) before calling the i52/u52 API.","If you genuinely need fractions, store them as f64 via setF64 instead."],"exampleFix":"// before\nModule.setHeapI52(offset, value /* 3.5 */);\n// after\nModule.setHeapI52(offset, Math.trunc(value));","handlingStrategy":"validation","validationCode":"if (!Number.isInteger(value)) throw new TypeError(`Expected an integer for i52 slot, got ${value}.`);","typeGuard":"function isIntegerNumber(v: unknown): v is number { return typeof v === 'number' && Number.isInteger(v); }","tryCatchPattern":null,"preventionTips":["Round with Math.trunc/Math.round before writing a 52-bit slot.","Validate Number.isInteger before calling setI52/setU52 (or setHeapI52/setHeapU52).","Use setF64 if you need to store fractional values."],"tags":["memory","types","integer","i52"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}