{"record":{"id":"f0b5e4b519e9cb05","repo":"dotnet/aspnetcore","slug":"byte-array-index-index-does-not-exist","errorCode":null,"errorMessage":"Byte array index '${index}' does not exist.","messagePattern":"Byte array index '(.+?)' does not exist\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts","lineNumber":744,"sourceCode":"\n  attachReviver(function reviveReference(key: any, value: any) {\n      if (value && typeof value === \"object\") {\n          if (value.hasOwnProperty(dotNetObjectRefKey)) {\n              return new DotNetObject(value[dotNetObjectRefKey], currentCallDispatcher!);\n          } else if (value.hasOwnProperty(jsObjectIdKey)) {\n              const id = value[jsObjectIdKey];\n              const jsObject = cachedJSObjectsById[id];\n\n              if (jsObject) {\n                  return jsObject.getWrappedObject();\n              }\n\n              throw new Error(`JS object instance with Id '${id}' does not exist. It may have been disposed.`);\n          } else if (value.hasOwnProperty(byteArrayRefKey)) {\n              const index = value[byteArrayRefKey];\n              const byteArray = currentCallDispatcher!.processByteArray(index);\n              if (byteArray === undefined) {\n                  throw new Error(`Byte array index '${index}' does not exist.`);\n              }\n              return byteArray;\n          } else if (value.hasOwnProperty(dotNetStreamRefKey)) {\n              const streamId = value[dotNetStreamRefKey];\n              const streamPromise = currentCallDispatcher!.getDotNetStreamPromise(streamId);\n              return new DotNetStream(streamPromise);\n          }\n      }\n\n      // Unrecognized - let another reviver handle it\n      return value;\n  });\n\n  class DotNetStream {\n      // eslint-disable-next-line no-empty-function\n      constructor(private readonly _streamPromise: Promise<ReadableStream>) {\n      }\n","sourceCodeStart":726,"sourceCodeEnd":762,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts#L726-L762","documentation":"Thrown in the reviveReference reviver when a payload carries a byte-array marker {byteArrayIndex: N} but processByteArray(index) (Microsoft.JSInterop.ts:505) returns nothing for that index. Byte arrays are pre-staged via receiveByteArray(id, data) before the JSON referencing them is revived; if the staging call was missed, mismatched, or already consumed, the index is absent. Note: the guard compares against 'undefined' while processByteArray returns null, so this branch is effectively unreachable in current code; the intent is to flag a missing staged byte array.","triggerScenarios":"A byte-array-bearing payload arriving without its preceding receiveByteArray call; a duplicated receiveByteArray consuming the same index twice; out-of-order framing where the JSON arrives before the byte staging; a custom serializer that omits the staging step. In shipped framing this is normally impossible, which is why the mismatched null/undefined check went unnoticed.","commonSituations":"Custom transports or test harnesses that hand-construct interop payloads; a framing regression; passing Uint8Array/IAsyncEnumerable byte segments out of order.","solutions":["If you custom-frame interop, always call receiveByteArray(id, bytes) before reviving the JSON that references that id.","Avoid reusing/ replaying captured payloads; let the framework produce them.","On framework versions, report the issue if it reproduces with stock framing (the null/undefined guard should be tightened).","Validate on the .NET side that byte arrays are sent via the supported API (IJSRuntime byte-array marshalling)."],"exampleFix":"// before (custom framing)\n// dispatcher revives JSON with {byteArrayIndex: 7} but never called receiveByteArray(7, data)\n\n// after\ndotNetCallDispatcher.receiveByteArray(7, bytes);\nconst value = parseJsonWithRevivers(dispatcher, jsonWithRef);","handlingStrategy":"validation","validationCode":"// when custom-framing, stage the byte array before reviving\ndotNetCallDispatcher.receiveByteArray(id, bytes);\nconst value = parseJsonWithRevivers(dotNetCallDispatcher, json);","typeGuard":"null","tryCatchPattern":"try { JSON.parse(json, defaultReviver); } catch (e) { if (/Byte array index/.test(e.message)) { /* re-stage then retry */ } else throw e; }","preventionTips":["Always call receiveByteArray before reviving byte-array-referencing JSON.","Avoid replaying captured interop payloads in fresh runtimes.","Let the framework produce byte-array framing rather than hand-rolling it."],"tags":["blazor","jsinterop","bytearray","serialization","framing","internal"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}