Skip to content

HotChocolate causes dotnet 8 Blazor application to be incompatible with hot-reload #6695

Description

@zaneclaes

Is there an existing issue for this?

  • I have searched the existing issues

Product

Hot Chocolate

Describe the bug

I never before had any problems with dotnet watch run and Hot Chocolate. Now, each time I save any file, the entire server needs to be restarted because the HotChocolate type inspector "has already been marked as initialized" (see logs).

This is also a relatively new project, which was created fresh with the new Blazor "Web App" template. It is 100% reproducible in this context, as well as in a new template app.

Steps to reproduce

  1. Create a Dotnet 8 Blazor "Web App" (the new template style with mixed client/server rendering)
  2. Add a basic hot chocolate schema to server
  3. (Optional) you may need to also add a Wasm app that is client side rendered, I'm not sure if this is what is breaking it
  4. Start the server with dotnet watch run
  5. Save one of the code-first schema files to trigger hot reload

Relevant log output

dotnet watch ⌚ File changed: ./Work/WorkMutations.cs.
[15:45:22 INF] Request starting HTTP/1.1 POST http://localhost:5292/_framework/blazor-hotreload - application/json 6440
[15:45:22 INF] Request finished HTTP/1.1 POST http://localhost:5292/_framework/blazor-hotreload - 200 0 null 4.5365ms
dotnet watch 🔥 Hot reload of changes succeeded.
[15:45:22 INF] Request starting HTTP/1.1 GET http://localhost:5292/scales - null null
[15:45:22 INF] Executing endpoint '/scales (/scales)'
[15:45:22 INF] Executed endpoint '/scales (/scales)'
[15:45:22 INF] HTTP GET /scales responded 200 in 5.1593 ms
[15:45:22 INF] Request finished HTTP/1.1 GET http://localhost:5292/scales - 200 null text/html; charset=utf-8 5.803ms
System.InvalidOperationException: The convention TuneDataTypeInspector has already been marked as initialized.
   at HotChocolate.Types.Descriptors.Convention.MarkInitialized()
   at HotChocolate.Types.Descriptors.Convention.Initialize(IConventionContext context)
   at HotChocolate.Types.Descriptors.DescriptorContext.GetConventionOrDefault[T](Func`1 defaultConvention, String scope)
   at HotChocolate.Types.Descriptors.DescriptorContextConventionExtensions.GetConventionOrDefault[T](IDescriptorContext context, T defaultConvention)
   at HotChocolate.Types.Descriptors.DescriptorContext.get_TypeInspector()
   at HotChocolate.SchemaBuilder.Setup.CreateTypeReferences(SchemaBuilder builder, IDescriptorContext context)
   at HotChocolate.SchemaBuilder.Setup.Create(SchemaBuilder builder, LazySchema lazySchema, IDescriptorContext context)
   at HotChocolate.SchemaBuilder.Create(IDescriptorContext context)
   at HotChocolate.SchemaBuilder.HotChocolate.ISchemaBuilder.Create(IDescriptorContext context)
   at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaAsync(ConfigurationContext context, RequestExecutorSetup setup, RequestExecutorOptions executorOptions, IServiceProvider schemaServices, TypeModuleChangeMonitor typeModuleChangeMonitor, CancellationToken cancellationToken)
   at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaServicesAsync(ConfigurationContext context, RequestExecutorSetup setup, CancellationToken cancellationToken)
   at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorNoLockAsync(String schemaName, CancellationToken cancellationToken)
   at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorAsync(String schemaName, CancellationToken cancellationToken)
   at Tuneality.Web.Server.Work.WorkExtensions.ExecuteInternalApiCall(IQueryRequestBuilder req, ITuneContext context)
   at Tuneality.Web.Server.Work.WorkDispatcher.Dispatch(String func, TimeSpan dt)
   at Tuneality.Web.Server.Work.WorkDispatcher.RunTask(TimeSpan dt)
   at Tuneality.Core.Lib.Utils.Tasks.<>c__DisplayClass3_0`1.<<ForeverLoop>b__0>d.MoveNext() in 

Additional Context?

My data type inspector is very simple:

public class TuneDataTypeInspector : DefaultTypeInspector {
  public override bool IsMemberIgnored(MemberInfo member) {
    return base.IsMemberIgnored(member) || member.IsDefined(typeof(ApiIgnoreAttribute));
  }
}

Version

14.0.0-r7

Activity

  1. changed the title [-]HotChocolate with dotnet 8 Blazor application incompatible with hot-reload[/-] [+]HotChocolate causes dotnet 8 Blazor application to be incompatible with hot-reload[/+] on Nov 12, 2023
  2. zaneclaes commented on Nov 13, 2023

    @zaneclaes
    Author

    @michaelstaib here's a minimal repro, with a brand new template app on version 14.0.0-p9. It's only about 10 lines of code added to the template. To repro, just dotnet watch run, open a browser to execute a GraphQL request, then make a change to Query.cs to trigger hot reload, and try again:

    BlazorApp1.zip

    First try:
    Screenshot 2023-11-13 at 10 03 45 AM

    After a hot-reload:
    Screenshot 2023-11-13 at 10 02 03 AM

  3. zaneclaes commented on Nov 13, 2023

    @zaneclaes
    Author

    @michaelstaib I've found a work-around that is sucessful about 80% of the time (better than nothing, but still not very workable). My "fix" appears to demonstrate that the System.InvalidOperationException thrown by MarkInitialized is superfluous, but there must be some case it was designed for..? Is there a summary of why Convention cannot implement MarkInitialized idempotently? In my years using HotChocolate, 99.999% of my errors have come from this one exception.

    public class TuneDataTypeInspector : DefaultTypeInspector {
      protected override void Initialize(IConventionContext context) {
        // do not call the base class, so it does not throw an exception.
        if (!IsInitialized) base.Initialize(context);
      }
    }
    

    When the fix fails, the new error manifests in a way that "forgets" that ITuneContext is a [Service] passed into the mutation:

    [10:50:26 ERR] An unhandled exception has occurred while executing the request.
    HotChocolate.SchemaException: For more details look at the `Errors` property.
    
    1. Unable to infer or resolve a schema type from the type reference `ITuneContext (Input)`.
    
       at HotChocolate.Configuration.TypeInitializer.DiscoverTypes()
       at HotChocolate.Configuration.TypeInitializer.Initialize()
       at HotChocolate.SchemaBuilder.Setup.InitializeTypes(SchemaBuilder builder, IDescriptorContext context, IReadOnlyList`1 types)
       at HotChocolate.SchemaBuilder.Setup.Create(SchemaBuilder builder, LazySchema lazySchema, IDescriptorContext context)
       at HotChocolate.SchemaBuilder.Create(IDescriptorContext context)
       at HotChocolate.SchemaBuilder.HotChocolate.ISchemaBuilder.Create(IDescriptorContext context)
       at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaAsync(ConfigurationContext context, RequestExecutorSetup setup, RequestExecutorOptions executorOptions, IServiceProvider schemaServices, TypeModuleChangeMonitor typeModuleChangeMonitor, CancellationToken cancellationToken)
       at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaServicesAsync(ConfigurationContext context, RequestExecutorSetup setup, CancellationToken cancellationToken)
       at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorNoLockAsync(String schemaName, CancellationToken cancellationToken)
       at HotChocolate.Execution.RequestExecutorResolver.GetRequestExecutorAsync(String schemaName, CancellationToken cancellationToken)
       at HotChocolate.Execution.RequestExecutorProxy.GetRequestExecutorAsync(CancellationToken cancellationToken)
       at HotChocolate.AspNetCore.HttpPostMiddlewareBase.HandleRequestAsync(HttpContext context)
       at HotChocolate.AspNetCore.HttpPostMiddlewareBase.InvokeAsync(HttpContext context)
       at Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.<>c__DisplayClass19_0.<<UseCancellation>b__1>d.MoveNext()
    --- End of stack trace from previous location ---
       at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
       at Serilog.AspNetCore.RequestLoggingMiddleware.Invoke(HttpContext httpContext)
       at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddlewareImpl.<Invoke>g__Awaited|10_0(ExceptionHandlerMiddlewareImpl middleware, HttpContext context, Task task)
    

    I am guessing this new error is caused when the method signature itself changes in some way, such that the invocation reference is messed up..? Because adding new methods to the Query/Mutation classes also fails (it simply does not pick them up).

    However, editing the contents of the methods seems to hot reload successfully, and when I run into one of the above limitations it only affects the modified/added method, not the rest of the server...

    ... so this at least prevents my server from becoming totally unresponsive to any request.

  4. added 2 commits that reference this issue on Feb 27, 2026
    06fb490
    f08fc83
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions