{"record":{"id":"4e5cdf7fca78a105","repo":"dotnet/aspnetcore","slug":"no-call-dispatcher-has-been-set","errorCode":null,"errorMessage":"No call dispatcher has been set.","messagePattern":"No call dispatcher has been set\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts","lineNumber":255,"sourceCode":"\n  function parseJsonWithRevivers(callDispatcher: CallDispatcher, json: string | null): any {\n      currentCallDispatcher = callDispatcher;\n      const result = json ? JSON.parse(json, (key, initialValue) => {\n          // Invoke each reviver in order, passing the output from the previous reviver,\n          // so that each one gets a chance to transform the value\n\n          return jsonRevivers.reduce(\n              (latestValue, reviver) => reviver(key, latestValue),\n              initialValue\n          );\n      }) : null;\n      currentCallDispatcher = undefined;\n      return result;\n  }\n\n  function getDefaultCallDispatcher(): CallDispatcher {\n      if (defaultCallDispatcher === undefined) {\n          throw new Error(\"No call dispatcher has been set.\");\n      } else if (defaultCallDispatcher === null) {\n          throw new Error(\"There are multiple .NET runtimes present, so a default dispatcher could not be resolved. Use DotNetObject to invoke .NET instance methods.\");\n      } else {\n          return defaultCallDispatcher;\n      }\n  }\n\n  interface PendingAsyncCall<T> {\n    resolve: (value?: T | PromiseLike<T>) => void;\n    reject: (reason?: any) => void;\n  }\n\n  /**\n   * Represents the type of result expected from a JS interop call.\n   */\n  // eslint-disable-next-line no-shadow\n  export enum JSCallResultType {\n    Default = 0,","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts#L237-L273","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)."],"exampleFix":"// before — runs before Blazor boots\nDotNet.invokeMethodAsync('MyAssembly', 'DoThing'); // throws\n\n// after\nawait Blazor.start();\nDotNet.invokeMethodAsync('MyAssembly', 'DoThing');","handlingStrategy":"validation","validationCode":"import { getDefaultCallDispatcher } ... ; // not exported; instead track readiness\nlet blazorReady = false;\nBlazor.start().then(() => { blazorReady = true; });\nfunction canInvokeStatic(): boolean { return blazorReady; }","typeGuard":null,"tryCatchPattern":"try {\n  await DotNet.invokeMethodAsync('Asm', 'Method');\n} catch (e) {\n  if (/No call dispatcher/i.test(e.message)) {\n    await Blazor.start();\n    await DotNet.invokeMethodAsync('Asm', 'Method');\n  } else { throw e; }\n}","preventionTips":["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."],"tags":["jsinterop","blazor","interop","startup","runtime-initialization","race"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}