{"record":{"id":"95b5dd19bb3584c7","repo":"dotnet/aspnetcore","slug":"the-current-dispatcher-does-not-support-synchronou","errorCode":null,"errorMessage":"The current dispatcher does not support synchronous calls from JS to .NET. Use invokeDotNetMethodAsync instead.","messagePattern":"The current dispatcher does not support synchronous calls from JS to \\.NET\\. Use invokeDotNetMethodAsync instead\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts","lineNumber":477,"sourceCode":"          this.completePendingCall(parseInt(asyncCallId, 10), success, resultOrError);\n      }\n\n      invokeDotNetStaticMethod<T>(assemblyName: string, methodIdentifier: string, ...args: any[]): T | null {\n          return this.invokeDotNetMethod<T>(assemblyName, methodIdentifier, null, args);\n      }\n\n      invokeDotNetStaticMethodAsync<T>(assemblyName: string, methodIdentifier: string, ...args: any[]): Promise<T> {\n          return this.invokeDotNetMethodAsync<T>(assemblyName, methodIdentifier, null, args);\n      }\n\n      invokeDotNetMethod<T>(assemblyName: string | null, methodIdentifier: string, dotNetObjectId: number | null, args: any[] | null): T | null {\n          if (this._dotNetCallDispatcher.invokeDotNetFromJS) {\n              const argsJson = stringifyArgs(this, args);\n              const resultJson = this._dotNetCallDispatcher.invokeDotNetFromJS(assemblyName, methodIdentifier, dotNetObjectId, argsJson);\n              return resultJson ? parseJsonWithRevivers(this, resultJson) : null;\n          }\n\n          throw new Error(\"The current dispatcher does not support synchronous calls from JS to .NET. Use invokeDotNetMethodAsync instead.\");\n      }\n\n      invokeDotNetMethodAsync<T>(assemblyName: string | null, methodIdentifier: string, dotNetObjectId: number | null, args: any[] | null): Promise<T> {\n          if (assemblyName && dotNetObjectId) {\n              throw new Error(`For instance method calls, assemblyName should be null. Received '${assemblyName}'.`);\n          }\n\n          const asyncCallId = this._nextAsyncCallId++;\n          const resultPromise = new Promise<T>((resolve, reject) => {\n              this._pendingAsyncCalls[asyncCallId] = { resolve, reject };\n          });\n\n          try {\n              const argsJson = stringifyArgs(this, args);\n              this._dotNetCallDispatcher.beginInvokeDotNetFromJS(asyncCallId, assemblyName, methodIdentifier, dotNetObjectId, argsJson);\n          } catch (ex) {\n              // Synchronous failure\n              this.completePendingCall(asyncCallId, false, ex);","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts#L459-L495","documentation":"Thrown by CallDispatcher.invokeDotNetMethod() (the synchronous path) when the underlying DotNetCallDispatcher does not implement invokeDotNetFromJS. Synchronous JS-to-.NET calls are only supported on runtimes that opt in (e.g., Blazor WebAssembly); Blazor Server and other remote runtimes only support the async path.","triggerScenarios":"Calling DotNet.invokeMethod or DotNetObject.invokeMethod (synchronous) under Blazor Server or any host whose dispatcher lacks invokeDotNetFromJS. The check `if (this._dotNetCallDispatcher.invokeDotNetFromJS)` is false, so it throws.","commonSituations":"Code written and tested under Blazor WebAssembly (sync works) then deployed on Blazor Server (sync unsupported); using a third-party host that only wires beginInvokeDotNetFromJS; calling the deprecated DotNet.invokeMethod in a Server project.","solutions":["Switch to the async variant: DotNet.invokeMethodAsync or DotNetObject.invokeMethodAsync.","If you control the host, implement invokeDotNetFromJS on your DotNetCallDispatcher to enable sync calls.","Audit for any .invokeMethod( synchronous calls and convert them."],"exampleFix":"// before\nconst result = DotNet.invokeMethod('MyLib', 'Compute', input); // sync\n\n// after\nconst result = await DotNet.invokeMethodAsync('MyLib', 'Compute', input);","handlingStrategy":"validation","validationCode":"// Always prefer the async API; it works on all hosts.\nconst result = await DotNet.invokeMethodAsync('MyLib', 'Compute', input);","typeGuard":"function supportsSyncInvoke(dispatcher) { return typeof dispatcher.getDotNetCallDispatcher().invokeDotNetFromJS === 'function'; }","tryCatchPattern":"try { return DotNet.invokeMethod('MyLib', 'Method'); } catch (e) { if (/does not support synchronous calls/.test(e.message)) { return await DotNet.invokeMethodAsync('MyLib', 'Method'); } throw e; }","preventionTips":["Default to invokeMethodAsync everywhere; reserve sync calls for WebAssembly-only code.","Document the host requirement for any synchronous interop call.","Search the codebase for .invokeMethod( and convert to async during Server ports."],"tags":["js-interop","blazor","dispatcher","sync","blazor-server"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}