dotnet / dotnet/sdk

StaticWebAssets FUTDC does not track referenced project static web asset changes

Open
#53,425 0 comments 1 reaction 2 assignees Claimed by @javiercn View on GitHub
Area-AspNetCore untriaged
Dominant language
C#
Stars
3.2k
Forks
1.3k
PR merge metrics
PR metrics pending

Description

## Summary

When a Blazor Web App with WebAssembly + Global interactivity has a CSS file modified in the Client project and the app is restarted from Visual Studio, the Server project's build is skipped by VS's Fast Up-to-Date Check (FUTDC). This leaves the Server's `.staticwebassets.endpoints.json` manifest stale with old fingerprints and ETags, causing the app to fail at runtime with "An unhandled error has occurred."

The issue was identified while investigating [dotnet/aspnetcore#65738](https://github.com/dotnet/aspnetcore/issues/65738).

## Reproduction

1. Create a new .NET 10 Blazor Web App with WebAssembly + Global interactivity in VS.
2. Run the project (Ctrl+F5 or F5).
3. Stop the app.
4. Modify `MainLayout.razor.css` in the Client project (e.g., change a `background-color`).
5. Run the project again (Ctrl+F5).
6. The page fails with "An unhandled error has occurred." Reload does not help.

**Workaround:** Right-click the Client project in Solution Explorer and select "Rebuild" before running.

## Root cause

The SDK has an existing mechanism for tracking cross-project static web asset dependencies for FUTDC, but it has a timing bug that prevents it from working.

### The existing mechanism

1. **Build-time target `ResolveReferencedProjectsStaticWebAssetsConfiguration`** (`Microsoft.NET.Sdk.StaticWebAssets.References.targets`) writes referenced project `BuildManifestPath` values to `staticwebassets.references.upToDateCheck.txt`.

2. **Design-time target `CollectStaticWebAssetInputsDesignTime`** (`Microsoft.NET.Sdk.StaticWebAssets.Design.targets`) reads this file and adds the paths as `UpToDateCheckInput` items in `Set="StaticWebAssets"`.

### The timing bug

`ResolveReferencedProjectsStaticWebAssetsConfiguration` is a **build-time** target. `CollectStaticWebAssetInputsDesignTime` is a **design-time** target hooked into `CollectUpToDateCheckInputDesignTimeDependsOn`.

On initial project load, VS runs the design-time target **before any build has occurred**. At that point, `staticwebassets.references.upToDateCheck.txt` does not exist yet. The `Condition="Exists(...)"` causes `ReadLinesFromFile` to be skipped, and VS CPS caches the empty `_StaticWebAssetReferenceUpToDateCheckInput` result. Subsequent full builds create the file, but the design-time cache is never invalidated because intermediate output file changes do not trigger design-time re-evaluation.

### How this was established

1. VS FUTDC verbose logging confirmed the Server project's `UpToDateCheckInput` items in `Set="StaticWebAssets"` only contained Server-owned wwwroot files. No Client project static web asset outputs were listed.
2. The `staticwebassets.references.upToDateCheck.txt` file existed on disk and correctly contained the Client's `staticwebassets.build.json` path.
3. Direct ETag comparison confirmed the stale manifest: the Server bin had ETags from the initial build (fingerprint `69a47x8btv`) while the Client had regenerated with a new fingerprint (`w5s9wppyq9`).
4. Manually adding `` to the Server `.csproj` fixed the issue, confirming the root cause.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.