dotnet/aspnetcore · error · Error
There are multiple .NET runtimes present, so a default…
Error message
There are multiple .NET runtimes present, so a default dispatcher could not be resolved. Use DotNetObject to invoke .NET instance methods.
What it means
Thrown by getDefaultCallDispatcher() when defaultCallDispatcher is null, meaning attachDispatcher() was called more than once with different dispatchers. With multiple .NET runtimes loaded there is no single 'default' to route legacy static-style calls to, so the library refuses to guess. Callers must use a specific DotNetObject or dispatcher instance instead.
Solutions
- Use a DotNetObjectReference from .NET and call invokeMethodAsync on that specific instance instead of the module-level DotNet.invokeMethodAsync.
- Capture the specific ICallDispatcher returned by attachDispatcher and call invokeDotNetStaticMethodAsync on it.
- Reduce to a single Blazor runtime per page if possible.
Example fix
// before (ambiguous default)
DotNet.invokeMethodAsync('MyLib', 'DoThing');
// after (use the specific dispatcher / instance)
const dispatcher = DotNet.attachDispatcher(myDispatcher);
dispatcher.invokeDotNetStaticMethodAsync('MyLib', 'DoThing');
// or, from .NET, pass a DotNetObjectReference and call .invokeMethodAsync on it in JS Defensive patterns
Strategy: validation
Validate before calling
// Use a specific dispatcher / instance instead of the module-level default.
const dispatcher = DotNet.attachDispatcher(myDispatcher);
await dispatcher.invokeDotNetStaticMethodAsync('MyLib', 'Method');
// or receive a DotNetObjectReference from .NET and call invokeMethodAsync on it. Try / catch
try { return await DotNet.invokeMethodAsync('MyLib', 'Method'); } catch (e) { if (/multiple .NET runtimes/.test(e.message)) { console.error('Use a specific DotNetObjectReference or captured dispatcher.'); } throw e; } Prevention
- Prefer DotNetObjectReference-based calls over module-level DotNet.invokeMethod*.
- Capture the ICallDispatcher returned by attachDispatcher and route calls through it.
- Load only one Blazor runtime per page when possible.
When it happens
Trigger: Loading two Blazor runtimes on the same page (e.g., two Blazor WebAssembly roots, or Blazor Server + Blazor WebAssembly), each calling attachDispatcher. Then calling DotNet.invokeMethod / invokeMethodAsync (the module-level legacy APIs) hits the null default.
Common situations: Embedding multiple Blazor components from different apps on one page; mixing Blazor WebAssembly and Blazor Server in a host shell; testing harness that loads the runtime twice.
Related errors
- No call dispatcher has been set.
- For instance method calls, assemblyName should be null…
- JS object instance with ID
- The current dispatcher does not support synchronous calls…
- There is no pending async call with ID
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/249f71f05c9f3188.
Report an issue: GitHub.
Appendix: source
Thrown at src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts:257
currentCallDispatcher = callDispatcher;
const result = json ? JSON.parse(json, (key, initialValue) => {
// Invoke each reviver in order, passing the output from the previous reviver,
// so that each one gets a chance to transform the value
return jsonRevivers.reduce(
(latestValue, reviver) => reviver(key, latestValue),
initialValue
);
}) : null;
currentCallDispatcher = undefined;
return result;
}
function getDefaultCallDispatcher(): CallDispatcher {
if (defaultCallDispatcher === undefined) {
throw new Error("No call dispatcher has been set.");
} else if (defaultCallDispatcher === null) {
throw new Error("There are multiple .NET runtimes present, so a default dispatcher could not be resolved. Use DotNetObject to invoke .NET instance methods.");
} else {
return defaultCallDispatcher;
}
}
interface PendingAsyncCall<T> {
resolve: (value?: T | PromiseLike<T>) => void;
reject: (reason?: any) => void;
}
/**
* Represents the type of result expected from a JS interop call.
*/
// eslint-disable-next-line no-shadow
export enum JSCallResultType {
Default = 0,
JSObjectReference = 1,
JSStreamReference = 2,View on GitHub (pinned to 3600ca084e)