aspnetcore icon indicating copy to clipboard operation
aspnetcore copied to clipboard

Tag helpers break dotnet watch hot reload

Open dstockhammer opened this issue 1 year ago • 9 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

Using any custom tag helper breaks dotnet watch hot reload in Razor Pages with System.TypeLoadException:

> dotnet watch
dotnet watch 🔥 Hot reload enabled. For a list of supported edits, see https://aka.ms/dotnet/hot-reload.
  💡 Press "Ctrl + R" to restart.
dotnet watch 🔧 Building...
  Determining projects to restore...
  All projects are up-to-date for restore.
  HotReloadRepro -> D:\workspace\hot-reload-repro\bin\Debug\net6.0\HotReloadRepro.dll
dotnet watch 🚀 Started
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://localhost:7179
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5016
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: D:\workspace\hot-reload-repro\
dotnet watch ⌚ File changed: .\Pages\Index.cshtml.
dotnet watch 🔥 Hot reload of changes succeeded.
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
fail: Microsoft.AspNetCore.Server.Kestrel[13]
      Connection id "0HMK832AIMGVR", Request id "0HMK832AIMGVR:00000013": An unhandled exception was thrown by the application.
      System.AggregateException: An error occurred while writing to logger(s). (Could not load type 'HotReloadRepro.Pages.Pages_Index+<ExecuteAsync>d__8#1' from assembly 'HotReloadRepro, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.) (Could not load type 'HotReloadRepro.Pages.Pages_Index+<ExecuteAsync>d__8#1' from assembly 'HotReloadRepro, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.)
       ---> System.TypeLoadException: Could not load type 'HotReloadRepro.Pages.Pages_Index+<ExecuteAsync>d__8#1' from assembly 'HotReloadRepro, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
         at System.Reflection.CustomAttribute._CreateCaObject(RuntimeModule pModule, RuntimeType type, IRuntimeMethodInfo pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
         at System.Reflection.CustomAttribute.AddCustomAttributes(ListBuilder`1& attributes, RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1 derivedAttributes)
         at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType)
         at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, Boolean inherit)
         at System.Reflection.RuntimeMethodInfo.GetCustomAttributes(Type attributeType, Boolean inherit)
         at System.Attribute.GetCustomAttributes(MemberInfo element, Type attributeType, Boolean inherit)
         at System.Reflection.CustomAttributeExtensions.GetCustomAttributes[T](MemberInfo element, Boolean inherit)
         at System.Diagnostics.StackTrace.TryResolveStateMachineMethod(MethodBase& method, Type& declaringType)
         at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat, StringBuilder sb)
         at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat)
         at System.Exception.get_StackTrace()
         at System.Exception.ToString()
         at Microsoft.Extensions.Logging.Console.SimpleConsoleFormatter.CreateDefaultLogMessage[TState](TextWriter textWriter, LogEntry`1& logEntry, String message, IExternalScopeProvider scopeProvider)
         at Microsoft.Extensions.Logging.Console.SimpleConsoleFormatter.Write[TState](LogEntry`1& logEntry, IExternalScopeProvider scopeProvider, TextWriter textWriter)
         at Microsoft.Extensions.Logging.Console.ConsoleLogger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
         at Microsoft.Extensions.Logging.Logger.<Log>g__LoggerLog|12_0[TState](LogLevel logLevel, EventId eventId, ILogger logger, Exception exception, Func`3 formatter, List`1& exceptions, TState& state)
         --- End of inner exception stack trace ---
         at Microsoft.Extensions.Logging.Logger.ThrowLoggingError(List`1 exceptions)
         at Microsoft.Extensions.Logging.Logger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
         at Microsoft.Extensions.Logging.Logger`1.Microsoft.Extensions.Logging.ILogger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
         at Microsoft.Extensions.Logging.LoggerMessage.<>c__DisplayClass8_0.<Define>g__Log|0(ILogger logger, Exception exception)
         at Microsoft.AspNetCore.Diagnostics.DiagnosticsLoggerExtensions.UnhandledException(ILogger logger, Exception exception)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Watch.BrowserRefresh.BrowserRefreshMiddleware.InvokeAsync(HttpContext context)
         at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
       ---> (Inner Exception #1) System.TypeLoadException: Could not load type 'HotReloadRepro.Pages.Pages_Index+<ExecuteAsync>d__8#1' from assembly 'HotReloadRepro, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
         at System.Reflection.CustomAttribute._CreateCaObject(RuntimeModule pModule, RuntimeType type, IRuntimeMethodInfo pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
         at System.Reflection.CustomAttribute.AddCustomAttributes(ListBuilder`1& attributes, RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1 derivedAttributes)
         at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType)
         at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, Boolean inherit)
         at System.Reflection.RuntimeMethodInfo.GetCustomAttributes(Type attributeType, Boolean inherit)
         at System.Attribute.GetCustomAttributes(MemberInfo element, Type attributeType, Boolean inherit)
         at System.Reflection.CustomAttributeExtensions.GetCustomAttributes[T](MemberInfo element, Boolean inherit)
         at System.Diagnostics.StackTrace.TryResolveStateMachineMethod(MethodBase& method, Type& declaringType)
         at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat, StringBuilder sb)
         at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat)
         at System.Exception.get_StackTrace()
         at System.Exception.ToString()
         at System.Text.StringBuilder.Append(Object value)
         at Microsoft.Extensions.Logging.EventLog.EventLogLogger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
         at Microsoft.Extensions.Logging.Logger.<Log>g__LoggerLog|12_0[TState](LogLevel logLevel, EventId eventId, ILogger logger, Exception exception, Func`3 formatter, List`1& exceptions, TState& state)<---

Expected Behavior

No response

Steps To Reproduce

The issue is very easy to reproduce:

  1. create a fresh Razor Pages project with dotnet new razor -> commit#3754a57
  2. create a custom tag helper and use in on the Index page (or any other page) -> commit#912f252
  3. run dotnet watch
  4. making any change that triggers a hot reload -> boom 💥

I've created a repository to demonstrate this issue: https://github.com/dstockhammer/hot-reload-repro

Exceptions (if any)

System.TypeLoadException: Could not load type 'HotReloadRepro.Pages.Pages_Index+<ExecuteAsync>d__8#1' from assembly 'HotReloadRepro, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
  at System.Reflection.CustomAttribute._CreateCaObject(RuntimeModule pModule, RuntimeType type, IRuntimeMethodInfo pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
  at System.Reflection.CustomAttribute.AddCustomAttributes(ListBuilder`1& attributes, RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1 derivedAttributes)
  at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType)
  at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, Boolean inherit)
  at System.Reflection.RuntimeMethodInfo.GetCustomAttributes(Type attributeType, Boolean inherit)
  at System.Attribute.GetCustomAttributes(MemberInfo element, Type attributeType, Boolean inherit)
  at System.Reflection.CustomAttributeExtensions.GetCustomAttributes[T](MemberInfo element, Boolean inherit)
  at System.Diagnostics.StackTrace.TryResolveStateMachineMethod(MethodBase& method, Type& declaringType)
  at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat, StringBuilder sb)
  at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat)
  at System.Exception.get_StackTrace()
  at System.Exception.ToString()
  at Microsoft.Extensions.Logging.Console.SimpleConsoleFormatter.CreateDefaultLogMessage[TState](TextWriter textWriter, LogEntry`1& logEntry, String message, IExternalScopeProvider scopeProvider)
  at Microsoft.Extensions.Logging.Console.SimpleConsoleFormatter.Write[TState](LogEntry`1& logEntry, IExternalScopeProvider scopeProvider, TextWriter textWriter)
  at Microsoft.Extensions.Logging.Console.ConsoleLogger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
  at Microsoft.Extensions.Logging.Logger.<Log>g__LoggerLog|12_0[TState](LogLevel logLevel, EventId eventId, ILogger logger, Exception exception, Func`3 formatter, List`1& exceptions, TState& state)
  --- End of inner exception stack trace ---
  at Microsoft.Extensions.Logging.Logger.ThrowLoggingError(List`1 exceptions)
  at Microsoft.Extensions.Logging.Logger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
  at Microsoft.Extensions.Logging.Logger`1.Microsoft.Extensions.Logging.ILogger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
  at Microsoft.Extensions.Logging.LoggerMessage.<>c__DisplayClass8_0.<Define>g__Log|0(ILogger logger, Exception exception)
  at Microsoft.AspNetCore.Diagnostics.DiagnosticsLoggerExtensions.UnhandledException(ILogger logger, Exception exception)
  at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
  at Microsoft.AspNetCore.Watch.BrowserRefresh.BrowserRefreshMiddleware.InvokeAsync(HttpContext context)
  at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
---> (Inner Exception #1) System.TypeLoadException: Could not load type 'HotReloadRepro.Pages.Pages_Index+<ExecuteAsync>d__8#1' from assembly 'HotReloadRepro, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
  at System.Reflection.CustomAttribute._CreateCaObject(RuntimeModule pModule, RuntimeType type, IRuntimeMethodInfo pCtor, Byte** ppBlob, Byte* pEndBlob, Int32* pcNamedArgs)
  at System.Reflection.CustomAttribute.AddCustomAttributes(ListBuilder`1& attributes, RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1 derivedAttributes)
  at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType)
  at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, Boolean inherit)
  at System.Reflection.RuntimeMethodInfo.GetCustomAttributes(Type attributeType, Boolean inherit)
  at System.Attribute.GetCustomAttributes(MemberInfo element, Type attributeType, Boolean inherit)
  at System.Reflection.CustomAttributeExtensions.GetCustomAttributes[T](MemberInfo element, Boolean inherit)
  at System.Diagnostics.StackTrace.TryResolveStateMachineMethod(MethodBase& method, Type& declaringType)
  at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat, StringBuilder sb)
  at System.Diagnostics.StackTrace.ToString(TraceFormat traceFormat)
  at System.Exception.get_StackTrace()
  at System.Exception.ToString()
  at System.Text.StringBuilder.Append(Object value)
  at Microsoft.Extensions.Logging.EventLog.EventLogLogger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
  at Microsoft.Extensions.Logging.Logger.<Log>g__LoggerLog|12_0[TState](LogLevel logLevel, EventId eventId, ILogger logger, Exception exception, Func`3 formatter, List`1& exceptions, TState& state)<---

.NET Version

6.0.400

Anything else?

I first encountered this issue with the latest 7.0 preview, so I initially assumed it's an issue in the preview. To make sure it's not an issue with my machine, I've completely uninstalled/deleted all dotnet SDKs and runtimes, then manually reinstalled the latest 6.0 SDK. I think the other runtimes listed here were just reinstalled by Windows Update.

> dotnet --info
.NET SDK (reflecting any global.json):
 Version:   6.0.400
 Commit:    7771abd614

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.19044
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\6.0.400\

global.json file:
  Not found

Host:
  Version:      6.0.8
  Architecture: x64
  Commit:       55fb7ef977

.NET SDKs installed:
  3.1.422 [C:\Program Files\dotnet\sdk]
  6.0.400 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 3.1.28 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 3.1.28 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.28 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Download .NET:
  https://aka.ms/dotnet-download

Learn about .NET Runtimes and SDKs:
  https://aka.ms/dotnet/runtimes-sdk-info

I found two other bug reports that look related:

  • https://github.com/dotnet/aspnetcore/issues/43450
  • https://stackoverflow.com/questions/73464052/asp-net-crashing-on-dotnet-watch-command

dstockhammer avatar Aug 27 '22 10:08 dstockhammer

@dstockhammer thanks for contacting us.

This is a known regression that was fixed recently, I am not sure if the fix is available already. @tmat

javiercn avatar Aug 27 '22 11:08 javiercn

Thanks! Can you estimate when a fix will be available, and is there a workaround for now? Not being able to use dotnet watch effectively completely breaks my development flow. Having to restart the app manually every time I change a line of markup is completely unacceptable... 😞

dstockhammer avatar Aug 28 '22 09:08 dstockhammer

This has been causing my app(s) to crash with every .cshtml file save (which triggers a hot reload instead of a restart of the app). As someone that works on server-rendered HTML applications, you can imagine that hot reload becomes pretty useless in this case.

I thought it was something I broke on my end. Glad to hear it's just a regression.

I'd love to know when a fix is expected to land!

seangwright avatar Aug 29 '22 14:08 seangwright

This should land on the next SDK release. You can try the nightlies available at https://github.com/dotnet/installer, the patch should be available soon if it isn't already in the nightly.

TanayParikh avatar Aug 30 '22 16:08 TanayParikh

Same bug here....

pkwieci1 avatar Sep 02 '22 12:09 pkwieci1

This is a brutal efficiency killer 😭

seangwright avatar Sep 09 '22 22:09 seangwright

any informations about the release of this fix?

GiampaoloGabba avatar Sep 10 '22 07:09 GiampaoloGabba

Looks like this is fixed with the 6.0.9 release

dotnetshadow avatar Sep 14 '22 02:09 dotnetshadow

I was building an web app and it was time to use view components. Until using view components, dotnet watch command worked perfectly but now, it throws the same error. To test that if it's caused by view components, I removed <vc:last-record /> from my .cshtml file and use dotnet watch. Once I changed .cshtml file, dotnet watch didn't throw error and reloaded the page. Then I added vc tag helper and dotnet watch threw the same error again. Besides I installed dotnet sdk 6.0.302 (a stackoverflow post suggestion) but it keeps throwing error. Edit: I tried this line of code: @await Component.InvokeAsync("LastRecord") instead of vc tag helper and hot reload (dotnet watch) is now working properly.

4Furki4 avatar Oct 14 '22 05:10 4Furki4