`dotnet watch` terminates with NullReferenceException in HotReloadClients.ApplyStaticAssetUpdatesAsync after Blazor static-asset edits
- Dominant language
- C#
- Stars
- 3.2k
- Forks
- 1.3k
- PR merge metrics
- PR metrics pending
Description
### Describe the bug
While developing a .NET 10 Blazor Interactive Server application, edits to CSS or JavaScript static assets trigger this failure with near certainty during ordinary development: the application shuts down and the parent `dotnet watch` process terminates with an unhandled `NullReferenceException`.
This is not a normal rude-edit restart. The watcher itself exits, so development cannot continue until it is manually restarted. During an initial concentrated tracking session, 19 incidents were formally recorded in approximately 13 hours and 42 minutes; 13 of those left a detached application child holding the HTTP port. Formal counting then stopped, but the same failure continued during later development sessions. Two fresh, identical CSS-only crashes on 2026-08-29 confirm that the issue remains active.
The initial application build succeeds. The solution is a Blazor Interactive Server web application with referenced Razor/component libraries and static web assets.
### Steps to reproduce
1. Use .NET SDK 10.0.400 on Windows 11 x64.
2. Start a `net10.0` Blazor Interactive Server project with `dotnet watch --project .\ChimeraBlazor\ChimeraBlazor.csproj --no-restore`.
3. Allow the initial build and application startup to complete.
4. Edit and save a `.razor` component.
5. After that update is processed, edit and save a file under `wwwroot`, commonly the global CSS file.
6. Repeat the normal edit cycle. In some runs, a CSS-only edit is sufficient.
7. Observe the application shutdown followed by the unhandled exception in `ApplyStaticAssetUpdatesAsync` and termination of the watcher parent.
The exact edit on which it fails varies, but repeated CSS/static-asset edits reliably reproduce the crash in this solution. It is not a rare intermittent event: 19 crashes were recorded in one concentrated session, and the same pattern has continued through subsequent development sessions. The production solution cannot be attached publicly, but a reduced reproduction can be prepared if requested.
### Expected behavior
A supported CSS or JavaScript update should be applied, or the application should be restarted while the watcher remains alive. An unsupported edit should produce the documented rude-edit/restart flow. A static-asset update must not terminate `dotnet watch` with an unhandled exception or leave a detached child process.
### Actual behavior
A CSS/static-asset update reports no managed-code changes, shuts down the application, and then terminates the watcher parent:
```text
dotnet watch File updated: .\ChimeraBlazor\wwwroot\Chimera.css
dotnet watch No managed code changes to apply.
Application is shutting down...
[ChimeraBlazor (net10.0)] Exited
dotnet watch An unexpected error occurred: System.NullReferenceException:
Object reference not set to an instance of an object.
at Microsoft.DotNet.HotReload.HotReloadClients.ApplyStaticAssetUpdatesAsync(...)
at Microsoft.DotNet.Watch.RunningProjectsManager.ApplyManagedCodeAndStaticAssetUpdatesAndRelaunchAsync(...)
at Microsoft.DotNet.Watch.HotReloadDotNetWatcher.WatchAsync(...)
at Microsoft.DotNet.Watch.Program.RunAsync()
```
The same signature has occurred repeatedly. In 13 of the initial 19 recorded incidents, a detached application child retained the development port and had to be stopped before a replacement watcher could start.
### Is this a regression?
Not yet tested against an earlier SDK feature band. The issue reproduces repeatedly with SDK 10.0.400 (commit 14fbf8d527).
### Are there any workarounds?
- Manually restarting the terminated watcher restores development until the next incident.
- `--no-hot-reload` avoids this code path but removes the workflow being tested.
- Waiting for each update to complete before the next save reduces ambiguity but does not eliminate CSS-only failures.
- Moving frequently edited CSS into Razor markup appeared to reduce frequency, but is not an acceptable general workaround.
### dotnet --info output
```console
.NET SDK:
Version: 10.0.400
Commit: 14fbf8d527
Workload version: 10.0.400-manifests.b0ae88bd
MSBuild version: 18.9.6+14fbf8d52
Runtime Environment:
OS Name: Windows
OS Version: 10.0.26200
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\10.0.400\
Host:
Version: 10.0.11
Architecture: x64
Commit: e2f47b0110
.NET SDKs installed:
10.0.400 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 3.1.32
Microsoft.AspNetCore.App 5.0.17
Microsoft.AspNetCore.App 8.0.30
Microsoft.AspNetCore.App 9.0.19
Microsoft.AspNetCore.App 10.0.11
Microsoft.NETCore.App 3.1.32
Microsoft.NETCore.App 5.0.17
Microsoft.NETCore.App 8.0.30
Microsoft.NETCore.App 9.0.19
Microsoft.NETCore.App 10.0.11
Microsoft.WindowsDesktop.App 3.1.32
Microsoft.WindowsDesktop.App 5.0.17
Microsoft.WindowsDesktop.App 8.0.30
Microsoft.WindowsDesktop.App 9.0.19
Microsoft.WindowsDesktop.App 10.0.11
Other architectures found:
x86 installed under Program Files (x86)
Environment variables:
DOTNET_WATCH_SUPPRESS_BROWSER_REFRESH=true
global.json file:
Not found
```
### IDE version
Not IDE-specific. Reproduced from PowerShell using the command-line dotnet watch process.
### Other details
- Target framework: `net10.0`
- Application type: Blazor Interactive Server
- Command-line PowerShell workflow; no IDE owns the Hot Reload session.
- CSS and JavaScript are documented supported static-asset Hot Reload inputs: https://learn.microsoft.com/dotnet/core/tools/dotnet-watch
- Fresh sanitized console evidence and environment details are attached.
No exact existing `dotnet/sdk` issue matching both `ApplyStaticAssetUpdatesAsync` and `NullReferenceException` was found before filing.
[DotNet-Watch-HotReload-Crash-20260829.txt](https://github.com/user-attachments/files/31607578/DotNet-Watch-HotReload-Crash-20260829.txt)
[DotNet-Info-20260829.txt](https://github.com/user-attachments/files/31607577/DotNet-Info-20260829.txt)
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the ApplyStaticAssetUpdatesAsync entry in the exception stack, then trace its callers in RunningProjectsManager and HotReloadDotNetWatcher. Reproduce with the documented dotnet watch command and the CSS or JavaScript edit sequence on SDK 10.0.400. Done means static-asset updates no longer produce an unhandled NullReferenceException, terminate the watcher, or leave a detached child process.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- cli, devtools, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100