{"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":"Error","httpStatus":null,"severity":"critical","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/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts#L237-L273","documentation":"Thrown by getDefaultCallDispatcher() when defaultCallDispatcher is still undefined, meaning DotNet.attachDispatcher() was never called. The default dispatcher is set by the Blazor runtime on startup; if it is missing, no .NET runtime is connected and any legacy DotNet.invokeMethod / invokeMethodAsync call has nowhere to route.","triggerScenarios":"Calling DotNet.invokeMethod or DotNet.invokeMethodAsync before Blazor has finished initializing (before Blazor.start() or before the auto-start script ran). Also when using the JS interop library standalone without attaching a dispatcher.","commonSituations":"A script in <head> or early <body> calling DotNet.invokeMethodAsync before Blazor is ready; using Microsoft.JSInterop.js outside of Blazor without a custom dispatcher; Blazor startup failed silently so attachDispatcher never ran.","solutions":["Wait for Blazor to be ready before calling: await Blazor.start(); or run code after the blazor:afterstarted event.","If using the library standalone, call DotNet.attachDispatcher(yourDispatcher) first.","Check the browser console for Blazor startup errors that prevented attachDispatcher."],"exampleFix":"// before\nDotNet.invokeMethodAsync('MyLib', 'DoThing'); // runs in <head>, Blazor not started\n\n// after\ndocument.addEventListener('blazor:afterstarted', () => {\n    DotNet.invokeMethodAsync('MyLib', 'DoThing');\n});","handlingStrategy":"validation","validationCode":"function isBlazorReady() { return typeof Blazor !== 'undefined' && Blazor._internal && defaultCallDispatcherSet; }\n// or simpler: wait for the event\ndocument.addEventListener('blazor:afterstarted', () => { /* safe to call DotNet.invokeMethodAsync */ });","typeGuard":null,"tryCatchPattern":"try { return await DotNet.invokeMethodAsync('MyLib', 'Method'); } catch (e) { if (/No call dispatcher has been set/.test(e.message)) { console.warn('Blazor not started yet; retry after blazor:afterstarted.'); } throw e; }","preventionTips":["Gate DotNet.invokeMethod* calls behind the Blazor started event.","If using the interop library standalone, attach a dispatcher explicitly.","Check the console for Blazor startup errors before debugging interop failures."],"tags":["js-interop","blazor","dispatcher","startup","lifecycle"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}