{"record":{"id":"249f71f05c9f3188","repo":"dotnet/aspnetcore","slug":"there-are-multiple-net-runtimes-present-so-a-def","errorCode":null,"errorMessage":"There are multiple .NET runtimes present, so a default dispatcher could not be resolved. Use DotNetObject to invoke .NET instance methods.","messagePattern":"There are multiple \\.NET runtimes present, so a default dispatcher could not be resolved\\. Use DotNetObject to invoke \\.NET instance methods\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts","lineNumber":257,"sourceCode":"      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,\n    JSObjectReference = 1,\n    JSStreamReference = 2,","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/JSInterop/Microsoft.JSInterop.JS/src/src/Microsoft.JSInterop.ts#L239-L275","documentation":"Thrown by getDefaultCallDispatcher() in Microsoft.JSInterop.ts (line 257) when defaultCallDispatcher is explicitly null — set that way by attachDispatcher() the moment a SECOND dispatcher is registered. With multiple .NET runtimes present, there is no safe 'default', so the static invokeMethod/invokeMethodAsync APIs refuse to guess. The error directs you to use DotNetObject (instance references) which carry their own dispatcher binding.","triggerScenarios":"Two or more .NET runtimes call attachDispatcher() in the same page (e.g., a Blazor Server circuit and a Blazor WebAssembly runtime, or two wasm runtimes). After the second attaches, defaultCallDispatcher is nulled and any subsequent static invokeMethodAsync throws this message.","commonSituations":"Blazor Web App with both Server and WebAssembly interactive runtimes on the same page (InteractiveAuto during handoff, or custom multi-runtime hosting). Hosting two Blazor apps on one page. Custom runtime embedding that registers multiple dispatchers. Migrating from single to multi-runtime without switching JS interop calls to instance-based DotNetObjectReference.","solutions":["Switch JS→.NET instance calls to use DotNetObjectReference: pass a [JSInvokable] object from .NET to JS and call invokeMethodAsync on that DotNetObject — it knows its own dispatcher.","For static methods, route through a specific runtime's dispatcher object instead of the global default.","If only one runtime is intended, ensure a second dispatcher is not being attached accidentally (double bootstrapping, stray script).","Refactor interop so each call is bound to the runtime that owns the target object."],"exampleFix":"// before — ambiguous with two runtimes\nDotNet.invokeMethodAsync('MyAssembly', 'DoThing'); // throws\n\n// after — instance-bound call\n// C#: dotNetRef = DotNetObjectReference.Create(this); passed to JS\n@code { [JSInvokable] public string DoThing() => \"ok\"; }\n// JS:\ndotNetRef.invokeMethodAsync('DoThing');","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isDotNetObject(v: any): v is { invokeMethodAsync: (...args: any[]) => Promise<any> } {\n  return v && typeof v.invokeMethodAsync === 'function' && typeof v['_id'] !== 'undefined';\n}","tryCatchPattern":null,"preventionTips":["Use DotNetObjectReference for instance calls in multi-runtime apps.","Avoid static invokeMethodAsync when more than one runtime may attach.","Bind each interop call to the runtime that owns the target.","Verify you are not double-bootstrapping runtimes."],"tags":["jsinterop","blazor","interop","multi-runtime","rendermode","dispatcher"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}