dotnet/aspnetcore · error
The current dispatcher does not support synchronous calls fr
Error message
The current dispatcher does not support synchronous calls from JS to .NET. Use invokeDotNetMethodAsync instead.
What it means
Thrown by DotNet.invokeDotNetMethod when the active call dispatcher has no synchronous invokeDotNetFromJS implementation. This is a capability mismatch: Blazor WebAssembly registers a synchronous dispatcher (the .NET runtime is in-process), but Blazor Server and other remoting-based hosts only expose beginInvokeDotNetFromJS because the call must cross a network boundary asynchronously. The message explicitly redirects you to the async path.
Source
Thrown at src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts:477
this.completePendingCall(parseInt(asyncCallId, 10), success, resultOrError);
}
invokeDotNetStaticMethod<T>(assemblyName: string, methodIdentifier: string, ...args: any[]): T | null {
return this.invokeDotNetMethod<T>(assemblyName, methodIdentifier, null, args);
}
invokeDotNetStaticMethodAsync<T>(assemblyName: string, methodIdentifier: string, ...args: any[]): Promise<T> {
return this.invokeDotNetMethodAsync<T>(assemblyName, methodIdentifier, null, args);
}
invokeDotNetMethod<T>(assemblyName: string | null, methodIdentifier: string, dotNetObjectId: number | null, args: any[] | null): T | null {
if (this._dotNetCallDispatcher.invokeDotNetFromJS) {
const argsJson = stringifyArgs(this, args);
const resultJson = this._dotNetCallDispatcher.invokeDotNetFromJS(assemblyName, methodIdentifier, dotNetObjectId, argsJson);
return resultJson ? parseJsonWithRevivers(this, resultJson) : null;
}
throw new Error("The current dispatcher does not support synchronous calls from JS to .NET. Use invokeDotNetMethodAsync instead.");
}
invokeDotNetMethodAsync<T>(assemblyName: string | null, methodIdentifier: string, dotNetObjectId: number | null, args: any[] | null): Promise<T> {
if (assemblyName && dotNetObjectId) {
throw new Error(`For instance method calls, assemblyName should be null. Received '${assemblyName}'.`);
}
const asyncCallId = this._nextAsyncCallId++;
const resultPromise = new Promise<T>((resolve, reject) => {
this._pendingAsyncCalls[asyncCallId] = { resolve, reject };
});
try {
const argsJson = stringifyArgs(this, args);
this._dotNetCallDispatcher.beginInvokeDotNetFromJS(asyncCallId, assemblyName, methodIdentifier, dotNetObjectId, argsJson);
} catch (ex) {
// Synchronous failure
this.completePendingCall(asyncCallId, false, ex);View on GitHub (pinned to 294cab2f9b)
Solutions
- Switch the JS call to the async variant: DotNet.invokeMethodAsync('MyAssembly','MyMethod') or dotNetRef.invokeMethodAsync('Method').
- If you control the call site, make the surrounding function async and await the result.
- Avoid DotNetObject.invokeMethod / DotNet.invokeMethod entirely in code that must run on Blazor Server; keep only the async overloads.
- If you truly need sync semantics, run that code only on Blazor WebAssembly and gate the host via feature detection.
Example fix
// before
const result = DotNet.invokeMethod('MyAssembly', 'Calculate', input);
// after
const result = await DotNet.invokeMethodAsync('MyAssembly', 'Calculate', input); Defensive patterns
Strategy: fallback
Validate before calling
function canSyncInvokeDotNet() {
// dispatcher is internal; approximate by host detection
return typeof Blazor !== 'undefined' && /WebAssembly/.test(navigator.userAgent) && location.protocol.startsWith('http');
} Type guard
type DotNetSyncCapable = { invokeMethod(...args:any[]): any };
function supportsSyncDotNet(d: any): d is DotNetSyncCapable {
return typeof d?.invokeMethod === 'function' && !String(d.invokeMethod).includes('throw');
} Try / catch
try {
DotNet.invokeMethod('Asm','M');
} catch (e) {
if (/Use invokeDotNetMethodAsync/.test(e.message)) {
return await DotNet.invokeMethodAsync('Asm','M');
}
throw e;
} Prevention
- Default to async overloads in all cross-host JS interop.
- Feature-detect the host before relying on sync semantics.
- Document each JS interop call as Server-safe or WASM-only.
When it happens
Trigger: Calling DotNet.invokeMethod / invokeMethodAsync-synchronously on a host that does not set _dotNetCallDispatcher.invokeDotNetFromJS. Concretely: a JS module calls DotNet.invokeMethod('MyAssembly','MyMethod') under Blazor Server, or a JS component calls dotNetRef.invokeMethod(...) (DotNetObject.invokeMethod at Microsoft.JSInterop.ts:710) on Blazor Server.
Common situations: Running the same JS interop code against Blazor Server that worked on Blazor WebAssembly; library code that assumed an in-process .NET runtime; misreading the docs and using the sync overload everywhere.
Related errors
- There is no pending async call with ID ${asyncCallId}.
- assembly must be defined when using a descriptor.
- typeName must be defined when using a descriptor.
- Cannot create a JSObjectReference from the value '${jsObject
- Cannot create a JSStreamReference from the value '${streamRe
AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06).
Data as JSON: /api/errors/95b5dd19bb3584c7.
Report an issue: GitHub.