{"record":{"id":"333c235e370a895a","repo":"dotnet/aspnetcore","slug":"cannot-read-uint64-with-high-order-part-highpart","errorCode":null,"errorMessage":"Cannot read uint64 with high order part ${highPart}, because the result would exceed Number.MAX_SAFE_INTEGER.","messagePattern":"Cannot read uint64 with high order part (.+?), because the result would exceed Number\\.MAX_SAFE_INTEGER\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/BinaryDecoder.ts","lineNumber":26,"sourceCode":"  return (buffer[position])\n        | (buffer[position + 1] << 8)\n        | (buffer[position + 2] << 16)\n        | (buffer[position + 3] << 24);\n}\n\nexport function readUint32LE(buffer: Uint8Array, position: number): any {\n  return (buffer[position])\n        + (buffer[position + 1] << 8)\n        + (buffer[position + 2] << 16)\n        + ((buffer[position + 3] << 24) >>> 0); // The >>> 0 coerces the value to unsigned\n}\n\nexport function readUint64LE(buffer: Uint8Array, position: number): any {\n  // This cannot be done using bit-shift operators in JavaScript, because\n  // those all implicitly convert to int32\n  const highPart = readUint32LE(buffer, position + 4);\n  if (highPart > maxSafeNumberHighPart) {\n    throw new Error(`Cannot read uint64 with high order part ${highPart}, because the result would exceed Number.MAX_SAFE_INTEGER.`);\n  }\n\n  return (highPart * uint64HighPartShift) + readUint32LE(buffer, position);\n}\n\nexport function readLEB128(buffer: Uint8Array, position: number): number {\n  let result = 0;\n  let shift = 0;\n  for (let index = 0; index < 4; index++) {\n    const byte = buffer[position + index];\n    result |= (byte & 127) << shift;\n    if (byte < 128) {\n      break;\n    }\n    shift += 7;\n  }\n  return result;\n}","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Web.JS/src/BinaryDecoder.ts#L8-L44","documentation":"Thrown by readUint64LE in BinaryDecoder when the high-order 32 bits of a little-endian uint64 read from a serialized interop buffer exceed 2^21-1, because combining such a high part with any low part would exceed Number.MAX_SAFE_INTEGER (2^53-1) and lose precision. The framework deliberately refuses rather than silently corrupt large ulong values.","triggerScenarios":"Serializing a System.UInt64 (or ulong) whose value is greater than ~2^53-1 (9,007,199,254,740,991) into a binary interop payload that Blazor's BinaryDecoder later reads. Common with large counters, snowflake IDs, timestamps in ticks, file sizes, or memory offsets.","commonSituations":"Twitter/Discord snowflake IDs, large primary keys, DateTime/Stopwatch ticks beyond safe range, file/stream offsets, high-resolution timestamps, or any ulong field flowing through JS interop.","solutions":["Pass large uint64 values as strings (toString()) instead of as native ulong, and parse on the receiving side with BigInt.","Change the parameter/return type to long (signed) only if values stay within safe integer range — this does not raise the ceiling.","Reduce the magnitude: send a derived/scaled value that fits in 53 bits and reconstruct on the other side.","Where possible, store large IDs as string on the .NET side so they never transit as numeric uint64."],"exampleFix":"// before — passing a snowflake ID as ulong throws when JS decodes it\n[Parameter] public ulong UserId { get; set; } // 64-bit value > 2^53\n\n// after — serialize as string and parse with BigInt in JS\n[Parameter] public string UserId { get; set; } // .NET: userId.ToString()\n// JS: const id = BigInt(user.userId);","handlingStrategy":"validation","validationCode":"// Pass large uint64 values as strings; never as native ulong through interop.\nconst MAX_SAFE = Number.MAX_SAFE_INTEGER;\nfunction safeUlong(value) {\n  return value > MAX_SAFE ? value.toString() : value;\n}","typeGuard":"function isSafeUint64(n) {\n  return Number.isInteger(n) && n >= 0 && n <= Number.MAX_SAFE_INTEGER;\n}","tryCatchPattern":"try {\n  await dotNet.invokeMethodAsync('PassId', bigId);\n} catch (e) {\n  if (/exceed Number.MAX_SAFE_INTEGER/.test(e.message)) {\n    await dotNet.invokeMethodAsync('PassId', bigId.toString());\n  } else throw e;\n}","preventionTips":["Model large IDs as strings on the .NET side.","Use BigInt on the JS side when precision matters.","Avoid sending timestamps in ticks; use ISO strings or milliseconds.","Audit interop signatures for ulong fields and convert before deployment."],"tags":["binary-decoder","interop","serialization","uint64","precision"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}