[StaticWebAssets] Replace opaque endpoint-manifest collision throw with a targeted BLAZOR107 diagnostic#54934
Draft
PureWeen wants to merge 1 commit into
Draft
Conversation
…th a targeted BLAZOR107 diagnostic When more than one static web asset resolves to the same target path for a given asset kind, GenerateStaticWebAssetEndpointsManifest (and the sibling GenerateStaticWebAssetsDevelopmentManifest) called ChooseNearestAssetKind(...).SingleOrDefault(), which throws a generic 'Sequence contains more than one element' exception. That message names neither the colliding assets nor where they came from, so it points investigators at this task instead of at the project or NuGet package that produced the duplicate asset (for example dotnet#54779, where the Microsoft.AspNetCore.Components.WebView package contributes a second 'All' blazor.modules.json fallback). Detect the ambiguous case explicitly and Log.LogError a BLAZOR107 diagnostic that lists each colliding asset's Identity/SourceId/SourceType/AssetKind/AssetMode and directs the fix to wherever the asset is produced. Selection behavior is otherwise unchanged: a single match is still chosen and zero matches still skips the group. Also document the producer-side contract on ChooseNearestAssetKind so the duplicate is not 'fixed' by silently collapsing it at the consumption site. Adds regression coverage for the dotnet#54779 three-asset collision and a no-false-positive test for the common 'All' + 'Publish' case. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When two static web assets resolve to the same target path,
GenerateStaticWebAssetEndpointsManifest(and its siblingGenerateStaticWebAssetsDevelopmentManifest) crashed with an opaqueInvalidOperationException: Sequence contains more than one elementfrom aSingleOrDefault()call. The message named neither the target path nor the colliding assets, so there was no signal about which project or package produced the duplicate.That opacity actively caused a misdiagnosis of #54779: with no provenance in the error, the natural instinct was to "fix" the SDK task that threw, rather than the upstream producer that generated the duplicate asset.
This PR replaces the throw at both call sites with a targeted
BLAZOR107diagnostic that names every colliding asset's provenance, so the next investigator (human or tooling) is pointed at the producer instead of the symptom.Note
This is diagnostic hardening, complementary to — not a substitute for — the actual fix for #54779. The collision in that issue originates in the
Microsoft.AspNetCore.Components.WebViewpackage and is being addressed in dotnet/aspnetcore. This change ensures that any future producer-side target-path collision fails loudly with actionable provenance.What changed
GenerateStaticWebAssetEndpointsManifest.cs— the throwing site.ChooseNearestAssetKind(...).SingleOrDefault()becomes.ToArray(); if more than one asset is yielded, logBLAZOR107(listing each asset) andcontinue; otherwise pick the single asset exactly as before.GenerateStaticWebAssetsDevelopmentManifest.cs— the same latentSingleOrDefault()pattern, given the same treatment.StaticWebAsset.ChooseNearestAssetKind— added an invariant comment documenting that yielding more than one asset means malformed producer-side input, and that callers must surfaceBLAZOR107rather than silently collapsing the duplicates here.Behavior is identical except on the error path: the
> 1branch fires in exactly the casesSingleOrDefault()previously threw; the single-asset and no-asset cases are unchanged.Example diagnostic output
Tests
Two regression tests in
GenerateStaticWebAssetEndpointsManifestTest:GenerateManifest_WhenMultipleAllAssetsCollideOnTargetPath_FailsWithBlazor107Diagnostic— reproduces the [Preview 6 regression]GenerateStaticWebAssetEndpointsManifestthrowsSequence contains more than one elementwhen a MAUI Blazor Hybrid project references a Razor class library and the BlazorWebView package #54779 collision shape (a packageAllasset + an app buildAllasset on the same target path) and asserts a singleBLAZOR107error naming the offending assets.GenerateManifest_WhenAllAndPublishAssetShareTargetPath_PicksPublishWithoutDiagnostic— guards against false positives: a normalAll+Publishpair must still resolve to thePublishasset with no error.Verified the regression test fails before this change (pre-fix logs a single uncoded error: "Sequence contains more than one element") and passes after. No regressions in the endpoints or development-manifest test classes.
Related to #54779.