{"record":{"id":"32b668194fbb158a","repo":"dotnet/aspnetcore","slug":"js-object-instance-with-id-targetinstanceid-doe","errorCode":null,"errorMessage":"JS object instance with ID ${targetInstanceId} does not exist (has it been disposed?).","messagePattern":"JS object instance with ID (.+?) does not exist \\(has it been disposed\\?\\)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts","lineNumber":578,"sourceCode":"      }\n  }\n\n  function formatError(error: Error | string): string {\n      if (error instanceof Error) {\n          return `${error.message}\\n${error.stack}`;\n      }\n\n      return error ? error.toString() : \"null\";\n  }\n\n  export function findJSFunction(identifier: string, targetInstanceId: number, callType?: JSCallType): Function {\n      const targetInstance = cachedJSObjectsById[targetInstanceId];\n\n      if (targetInstance) {\n          return targetInstance.resolveInvocationHandler(identifier, callType ?? JSCallType.FunctionCall);\n      }\n\n      throw new Error(`JS object instance with ID ${targetInstanceId} does not exist (has it been disposed?).`);\n  }\n\n  export function disposeJSObjectReferenceById(id: number) {\n      delete cachedJSObjectsById[id];\n  }\n\n  /**\n   * Traverses the object hierarchy to find an object member specified by the identifier.\n   *\n   * @param obj Root object to search in.\n   * @param identifier Complete identifier of the member to find, e.g. \"document.location.href\".\n   * @returns A tuple containing the immediate parent of the member and the member name.\n   */\n  export function findObjectMember(obj: any, identifier: string): [any, string] {\n      const keys = identifier.split(\".\");\n      let current = obj;\n\n      // First, we iterate over all but the last key. We throw error for missing intermediate keys.","sourceCodeStart":560,"sourceCodeEnd":596,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts#L560-L596","documentation":"Thrown by findJSFunction when cachedJSObjectsById[targetInstanceId] is undefined. Every JS object reference handed to .NET is cached by id; disposeJSObjectReferenceById (called when .NET disposes the JSObjectReference or a DotNetObject is GC'd) deletes that entry. A later call addressed to that id therefore cannot resolve the target.","triggerScenarios":".NET holds a JSObjectReference or ElementReference whose id was already disposed; calling jsRef.invokeMethod after the ref was disposed; an element reference that survived a re-render where the element was removed; calling on a DotNetObject after dispose.","commonSituations":"Holding a JSObjectReference in a long-lived service after IJSRuntime.Dispose or component disposal; using ElementReference across a re-render where the element unmounted; memory-pressure-driven GC of a DotNetObject that was not pinned.","solutions":["Null-out and stop using the reference after disposal; set jsRef = null in the .NET dispose path.","Capture a fresh reference each time the element/component mounts rather than reusing a stale one.","Pin DotNetObject instances with DotNetObjectReference.Create and dispose explicitly; keep the .NET side alive for the call's lifetime.","Guard the call: check the ref is valid before invoking."],"exampleFix":"// before\n@inject IJSRuntime JS\n@code {\n  private JSObjectReference _module;\n  protected override async Task OnAfterRenderAsync(bool first) {\n    if (first) _module = await JS.InvokeAsync<JSObjectReference>(\"import\",\"./lib.js\");\n  }\n  public void Dispose() { /* forgot to dispose _module */ }\n  async Task Late() => await _module.InvokeVoidAsync(\"fn\"); // stale id\n}\n\n// after\npublic async ValueTask DisposeAsync() {\n  if (_module is not null) { await _module.DisposeAsync(); _module = null; }\n}","handlingStrategy":"validation","validationCode":"// .NET: track validity\nprivate JSObjectReference _ref;\nprivate bool _disposed;\nasync Task CallAsync() {\n  if (_disposed || _ref is null) throw new ObjectDisposedException(nameof(_ref));\n  await _ref.InvokeVoidAsync(\"fn\");\n}","typeGuard":"null","tryCatchPattern":"try {\n  await jsRef.invokeMethodAsync('fn');\n} catch (e) {\n  if (/has it been disposed\\?/i.test(e.message)) { jsRef = null; /* reacquire */ }\n  else throw e;\n}","preventionTips":["Implement IAsyncDisposable and dispose JSObjectReference/DotNetObjectReference.","Set references to null after disposal.","Do not capture ElementReference across re-renders that may unmount the element."],"tags":["blazor","jsinterop","lifecycle","disposal","memory"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}