{"record":{"id":"84e2e8cceda2f63f","repo":"dotnet/aspnetcore","slug":"js-object-instance-with-id-id-does-not-exist","errorCode":null,"errorMessage":"JS object instance with Id '${id}' does not exist. It may have been disposed.","messagePattern":"JS object instance with Id '(.+?)' does not exist\\. It may have been disposed\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts","lineNumber":739,"sourceCode":"\n      public serializeAsArg() {\n          return { [dotNetObjectRefKey]: this._id };\n      }\n  }\n\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","sourceCodeStart":721,"sourceCodeEnd":757,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts#L721-L757","documentation":"Thrown by the built-in reviveReference JSON reviver when deserializing a payload that carries a __jsObjectId marker whose ID is not in cachedJSObjectsById. This fires during JSON.parse of arguments coming from .NET; the .NET side referenced a JS object that the JS runtime no longer holds (disposed or never existed on this client). Distinct from error 91 (which fires at call dispatch time); this fires during argument deserialization.","triggerScenarios":".NET sends back a JS object reference (e.g. round-tripping an IJSObjectReference) that was disposed on the JS side, or whose ID belongs to a different Blazor circuit/session. The reviver cannot resolve the marker to a wrapped object.","commonSituations":"Round-tripping a disposed IJSObjectReference; Blazor Server circuit reconnect where the JS-side object cache was reset but .NET still holds old IDs; cross-frame/cross-window references.","solutions":["Do not send disposed JS object references back from .NET; track disposal on the .NET side.","After a reconnect, re-establish JS references rather than reusing stale IDs.","Avoid persisting/serializing IJSObjectReference IDs across sessions."],"exampleFix":"// C# before\nvar jsRef = await JS.InvokeAsync<IJSObjectReference>(\"getRef\");\nawait jsRef.DisposeAsync();\nawait JS.InvokeVoidAsync(\"useRef\", jsRef); // sends disposed id -> reviver throws\n\n// after\nawait jsRef.DisposeAsync();\njsRef = null;\n// re-acquire before passing back","handlingStrategy":"validation","validationCode":"// .NET: do not pass disposed IJSObjectReference back to JS.\nif (jsRef is null || _disposed) { return; }\nawait JS.InvokeVoidAsync(\"useRef\", jsRef);","typeGuard":null,"tryCatchPattern":"try { /* call that round-trips a jsRef */ } catch (JSException e) when (e.Message.Contains(\"does not exist. It may have been disposed\")) { jsRef = null; /* re-acquire or stop using */ }","preventionTips":["Null out IJSObjectReference fields after DisposeAsync.","Never reuse JS object references across Blazor circuit reconnects.","Do not serialize or persist JS object IDs across sessions."],"tags":["js-interop","blazor","object-reference","disposed","serialization","reviver"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}