Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hot Reload -- Operation is not valid due to the current state of the object #5803

Closed
1 task done
glen-84 opened this issue Feb 7, 2023 · 5 comments · Fixed by #8079
Closed
1 task done

Hot Reload -- Operation is not valid due to the current state of the object #5803

glen-84 opened this issue Feb 7, 2023 · 5 comments · Fixed by #8079

Comments

@glen-84
Copy link
Collaborator

glen-84 commented Feb 7, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Product

Hot Chocolate

Describe the bug

With Hot Reload enabled for a while, I start seeing the exception listed below.

Steps to reproduce

  1. Run an HC v13 project with dotnet watch.
  2. After a while, or after certain code changes, an exception is thrown.

(I'm not able to be more specific.)

Relevant log output

HotChocolate.SchemaException: For more details look at the `Errors` property.

1. Operation is not valid due to the current state of the object. (HotChocolate.Types.StaticObjectTypeExtension)

   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(String schemaName, RequestExecutorSetup options, RequestExecutorOptions executorOptions, IServiceProvider serviceProvider, TypeModuleChangeMonitor typeModuleChangeMonitor, CancellationToken cancellationToken)
   at HotChocolate.Execution.RequestExecutorResolver.CreateSchemaServicesAsync(String schemaName, RequestExecutorSetup options, 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__DisplayClass20_0.<<UseCancellation>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Serilog.AspNetCore.RequestLoggingMiddleware.Invoke(HttpContext httpContext)

Additional Context?

No response

Version

13.0.0-rc.7

@jonmaylandvitrolife
Copy link

I'm observing a similar error on HC 13.8.1. Suddenly my api is in this state, and keep hitting the error on all queries. Unfortunately I don't know how to reproduce.

HotChocolate.SchemaException: For more details look at the Errors property.

  1. Operation is not valid due to the current state of the object. (HotChocolate.Types.UuidType)

    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.<b__1>d.MoveNext()
    --- End of stack trace from previous location ---
    at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
    at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
    at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
    at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

    It throws an InvalidOperationException in TypeSystemObjectBase.MarkInitialized() (for the UuidType), as _status = TypeStatus.Finalized

@glen-84
Copy link
Collaborator Author

glen-84 commented Mar 9, 2024

I just watch with --no-hot-reload.

@bneumann
Copy link

bneumann commented Sep 18, 2024

Hi guys,
I switched from 2 separate projects (1 Blazor WASM with dev server and 1 Backend API) to a hosted WASM solution (still two projects, but the backend has a dependency to the WASM project, builds and hosts it). Now this error occurs during hot reload and it is a really strange thing.
I can change anything on the backend code and it rebuilds just fine using hot reload, but if I dare to add a CSS class or a tag in a razor page, hot reload kicks in and after that this error happens.
The problem is, that my client application (the WASM Blazor) only gets an error 500 on all graphql calls and the exception page doesn't show anything because HotChocolate prevents the error from bubbling up.
So I replaced the Error Page with an error handler to inspect the mentioned "Errrors" property which was so gravefully covered and here is the StackTrace it gave me:

   at HotChocolate.Types.Descriptors.Convention`1.AssertUninitialized()
   at HotChocolate.Types.Descriptors.Convention`1.Initialize(IConventionContext context)
   at HotChocolate.Types.Descriptors.DescriptorContext.MergeExtensions(IConventionContext context, Convention convention, IList`1 extensions)
   at HotChocolate.Types.Descriptors.DescriptorContext.GetConventionOrDefault[T](Func`1 defaultConvention, String scope)
   at HotChocolate.Data.FilterDescriptorContextExtensions.GetFilterConvention(IDescriptorContext context, String scope)
   at HotChocolate.Types.FilterObjectFieldDescriptorExtensions.<>c__DisplayClass5_0.<UseFiltering>b__1(IDescriptorContext c, ObjectFieldDefinition definition)
   at HotChocolate.Types.Descriptors.DescriptorBase`1.<>c__DisplayClass19_0.<OnBeforeCreate>b__0(IDescriptorContext c, IDefinition d)
   at HotChocolate.Types.Descriptors.Definitions.CreateConfiguration.Configure(IDescriptorContext context)
   at HotChocolate.Types.Descriptors.DescriptorBase`1.CreateDefinition()
   at HotChocolate.Types.Descriptors.ObjectTypeDescriptor.OnCreateDefinition(ObjectTypeDefinition definition)
   at HotChocolate.Types.Descriptors.DescriptorBase`1.CreateDefinition()
   at HotChocolate.Types.ObjectType`1.CreateDefinition(ITypeDiscoveryContext context)
   at HotChocolate.Types.TypeSystemObjectBase`1.Initialize(ITypeDiscoveryContext context)
   at HotChocolate.Configuration.TypeRegistrar.InitializeType(TypeSystemObjectBase typeSystemObject, String scope, Boolean isInferred)

The only way this exception @glen-84 mentions Operation is not valid due to the current state of the object. could be triggered is when the definition is initialized but null. So my wild guess is, that hot reload somehow kills the definition object and let the initializer run once more, resulting in this behavior.
I also tried to get some information on how hot reload internally works because it seems a bit odd, that I change something in project A and things disappear in project B, but that's out of my league :/

If @michaelstaib can point me in a direction I would gladly contribute a PR.

Cheers

@th-fulcrum
Copy link

th-fulcrum commented Feb 27, 2025

@michaelstaib do you have any ideas with this? It's actually really annoying, our app is fairly large so having to do a full rebuild just because hot chocolate breaks after a hot reload is painful.

@michaelstaib
Copy link
Member

We will remove the Hot Reload handling completely with 15.1 which will give users the capability to implement this on their own.

This is how it in general it should work ... for Hot Reload .NET has a hook.
The hook looks like this:

[assembly: MetadataUpdateHandler(typeof(RequestExecutorResolver.ApplicationUpdateHandler))]

The update handler looks like the following:

internal static class ApplicationUpdateHandler
    {
        private static readonly List<Action> _actions = [];

        public static void RegisterForApplicationUpdate(Action action)
        {
            lock (_actions)
            {
                _actions.Add(action);
            }
        }

        public static void UpdateApplication(Type[]? updatedTypes)
        {
            lock (_actions)
            {
                foreach (var action in _actions)
                {
                    action();
                }
            }
        }
    }

The RequestExecutorResolver manages the GraphQL executors and will register itself with RegisterForApplicationUpdate.
Since its a singleton there should always be just a single one registered.

When a Hot Reload happens we get notified on UpdateApplication and this will trigger an eviction of all schemas. On the next incoming request a new schema should be constructed. But even when we had this working at points it was highly unstable. As types could exist in different versions etc.

With preview 11 tomorrow I will have removed this and you can try to get it working on your end.

In general we do not recommend to bundle the GraphQL server with Blazor and recommend to have separate hosts for this.

I am closing this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants