dotnet/aspnetcore · error
No call dispatcher has been set.
Error message
No call dispatcher has been set.
What it means
Thrown by getDefaultCallDispatcher() in Microsoft.JSInterop.ts (line 255) when defaultCallDispatcher is still undefined — i.e., no .NET runtime has attached a call dispatcher yet. Static interop entry points like DotNet.invokeMethodAsync need a default dispatcher to route the call; without one there is no .NET runtime to talk to, so the call cannot proceed.
Source
Thrown at src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts:255
function parseJsonWithRevivers(callDispatcher: CallDispatcher, json: string | null): any {
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,View on GitHub (pinned to 294cab2f9b)
Solutions
- Wait for Blazor to be ready before invoking .NET — listen for the Blazor start promise or the appropriate 'blazor:ready'/DOMContentLoaded-after-boot event.
- For instance methods, use a captured DotNetObjectReference passed from .NET to JS instead of the static invokeMethod APIs.
- Confirm the Blazor runtime script (blazor.web.js / blazor.webassembly.js) is loaded and Blazor.start() has resolved.
- Ensure exactly the expected runtime attaches a dispatcher (see error 79 for the multi-runtime case).
Example fix
// before — runs before Blazor boots
DotNet.invokeMethodAsync('MyAssembly', 'DoThing'); // throws
// after
await Blazor.start();
DotNet.invokeMethodAsync('MyAssembly', 'DoThing'); Defensive patterns
Strategy: validation
Validate before calling
import { getDefaultCallDispatcher } ... ; // not exported; instead track readiness
let blazorReady = false;
Blazor.start().then(() => { blazorReady = true; });
function canInvokeStatic(): boolean { return blazorReady; } Try / catch
try {
await DotNet.invokeMethodAsync('Asm', 'Method');
} catch (e) {
if (/No call dispatcher/i.test(e.message)) {
await Blazor.start();
await DotNet.invokeMethodAsync('Asm', 'Method');
} else { throw e; }
} Prevention
- Await Blazor.start() before any static interop call.
- Prefer DotNetObjectReference for instance calls.
- Listen for the Blazor ready event before invoking.
- Ensure the runtime script is loaded and bootstrapped.
When it happens
Trigger: Calling DotNet.invokeMethod / invokeMethodAsync (the static, non-DotNetObject forms) before any .NET runtime has called attachDispatcher(). Common when JS interop runs before Blazor has booted the .NET runtime (e.g., a script running on page load before Blazor.start completes).
Common situations: Calling DotNet.invokeMethodAsync from a DOMContentLoaded handler or inline script before Blazor initializes. Standalone JS that uses Microsoft.JSInterop without a .NET host attached. Race where the JS bundle runs before the wasm/Server runtime registers its dispatcher. Using the wrong interop API in a multi-runtime scenario.
Related errors
- Cannot create a JSObjectReference from the value '${jsObject
- Cannot create a JSStreamReference from the value '${streamRe
- Supplied value is not a typed array or blob.
- Cannot create a JSStreamReference from the value '${streamRe
- There are multiple .NET runtimes present, so a default dispa
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/4e5cdf7fca78a105.
Report an issue: GitHub.