dotnet/aspnetcore · error · Error
JS object instance with ID
Error message
JS object instance with ID ${targetInstanceId} does not exist (has it been disposed?). What it means
Thrown by DotNet.findJSFunction() when no cached JSObject exists for the given targetInstanceId. Every JS interop call from .NET targets an instance by numeric ID (0 = window); if that ID was disposed or never registered, the call cannot resolve. The most common cause is using a JS object reference after it was disposed.
Solutions
- Do not use an IJSObjectReference after calling Dispose on it.
- After Blazor reconnect, re-acquire JS object references rather than reusing old ones.
- Track disposal state on the .NET side and skip calls to disposed references.
Example fix
// C# before
await jsRef.InvokeVoidAsync("doThing");
await jsRef.DisposeAsync();
await jsRef.InvokeVoidAsync("doThing"); // throws in JS
// after
await jsRef.InvokeVoidAsync("doThing");
await jsRef.DisposeAsync();
jsRef = null; // null and re-acquire if needed Defensive patterns
Strategy: validation
Validate before calling
// .NET: null-check and dispose-track IJSObjectReference before invoking.
if (jsRef is null) { return; }
await jsRef.InvokeVoidAsync("doThing"); Try / catch
try { await jsRef.InvokeVoidAsync("doThing"); } catch (JSException e) when (e.Message.Contains("does not exist")) { jsRef = null; /* re-acquire or give up */ } Prevention
- Set IJSObjectReference to null immediately after DisposeAsync.
- Do not share JS object references across Blazor circuit reconnects.
- Track disposal state on the .NET side to avoid using stale handles.
When it happens
Trigger: .NET calls a JS function on an IJSObjectReference that was already disposed (or whose underlying object was garbage-collected via disposeJSObjectReferenceById). Also when the ID is stale after a Blazor circuit reconnect or page refresh.
Common situations: Calling a method on a disposed IJSObjectReference; holding a JS object reference across a Blazor Server reconnect that lost the cache; calling dispose on a reference then using it again.
Related errors
- JS object instance with Id
- Cannot create a JSObjectReference from the value
- Cannot create a JSStreamReference from the value
- No call dispatcher has been set.
- There are multiple .NET runtimes present, so a default…
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/32b668194fbb158a.
Report an issue: GitHub.
Appendix: source
Thrown at src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts:578
}
}
function formatError(error: Error | string): string {
if (error instanceof Error) {
return `${error.message}\n${error.stack}`;
}
return error ? error.toString() : "null";
}
export function findJSFunction(identifier: string, targetInstanceId: number, callType?: JSCallType): Function {
const targetInstance = cachedJSObjectsById[targetInstanceId];
if (targetInstance) {
return targetInstance.resolveInvocationHandler(identifier, callType ?? JSCallType.FunctionCall);
}
throw new Error(`JS object instance with ID ${targetInstanceId} does not exist (has it been disposed?).`);
}
export function disposeJSObjectReferenceById(id: number) {
delete cachedJSObjectsById[id];
}
/**
* Traverses the object hierarchy to find an object member specified by the identifier.
*
* @param obj Root object to search in.
* @param identifier Complete identifier of the member to find, e.g. "document.location.href".
* @returns A tuple containing the immediate parent of the member and the member name.
*/
export function findObjectMember(obj: any, identifier: string): [any, string] {
const keys = identifier.split(".");
let current = obj;
// First, we iterate over all but the last key. We throw error for missing intermediate keys.View on GitHub (pinned to 3600ca084e)