Skip to content

Align JS interop trimming warnings across synchronous and asynchronous APIs - #69687

Draft
PureWeen with Copilot wants to merge 5 commits into
mainfrom
copilot/fix-blazor-ijspinprocessobjectreference
Draft

PureWeen with Copilot wants to merge 5 commits into
mainfrom
copilot/fix-blazor-ijspinprocessobjectreference

Conversation

Copilot AI commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Align JS interop trimming warnings across synchronous and asynchronous APIs

  • You've read the Contributor Guide and Code of Conduct.
  • You've included unit or integration tests for your change, where applicable.
  • You've included inline docs for your change, where applicable.
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.

Apply consistent trimming warnings to JS interop serialization APIs.

Description

Synchronous JS interop APIs carry RequiresUnreferencedCode, while corresponding async APIs omit it. DynamicallyAccessedMembers does not cover nested object graphs or arbitrary serialized arguments, so both annotations remain necessary.

  • API annotations: Add matching warnings to async interfaces, implementations, and extension methods; retain existing generic-member annotations.
  • Void calls and disposal: Replace synchronous void-wrapper suppressions with warnings because arguments still require serialization. Keep disposal warning-free through a narrow suppression for its numeric object ID.
  • Regression coverage: Check warning presence, message consistency, and generic-member annotations across 12 API types.

Runtime behavior and method signatures are unchanged.

Copilot AI and others added 2 commits October 6, 2026 20:29
Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix RequiresUnreferencedCode attribute on IJSInProcessObjectReference.Invoke Align JS interop trimming warnings across synchronous and asynchronous APIs Oct 6, 2026
Copilot AI requested a review from PureWeen October 6, 2026 20:35
@PureWeen
PureWeen requested a balanced review from Copilot October 6, 2026 20:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The registered SSR runtime implementation is not aligned with the new interface annotation contract and can produce IL2046 warnings.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Aligns trimming diagnostics across synchronous and asynchronous JS interop serialization APIs.

Changes:

  • Adds consistent RequiresUnreferencedCode annotations.
  • Replaces unsafe void-call suppressions while narrowly suppressing disposal.
  • Adds reflection-based annotation regression tests.
File Description
src/​Components/​JSInterop/​test/​JSInteropTrimmingAnnotationsTest.cs Verifies annotation counts, messages, and generic-member preservation.
src/​Components/​JSInterop/​src/​JSRuntimeExtensions.cs Annotates asynchronous runtime extensions.
src/​Components/​JSInterop/​src/​JSRuntime.cs Annotates runtime serialization methods.
src/​Components/​JSInterop/​src/​JSObjectReferenceExtensions.cs Annotates object-reference extensions.
src/​Components/​JSInterop/​src/​JSInProcessRuntimeExtensions.cs Replaces the void-call suppression with a warning.
src/​Components/​JSInterop/​src/​JSInProcessObjectReferenceExtensions.cs Replaces the object-reference void-call suppression.
src/​Components/​JSInterop/​src/​Implementation/​JSObjectReference.cs Annotates implementations and narrowly suppresses disposal.
src/​Components/​JSInterop/​src/​IJSRuntime.cs Updates the runtime interface contract.
src/​Components/​JSInterop/​src/​IJSObjectReference.cs Updates the object-reference interface contract.

/// <param name="identifier">An identifier for the function to invoke. For example, the value <c>"someScope.someFunction"</c> will invoke the function <c>window.someScope.someFunction</c>.</param>
/// <param name="args">JSON-serializable arguments.</param>
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
@PureWeen

PureWeen commented Oct 7, 2026

Copy link
Copy Markdown
Member

@copilot Please address the CCR review comment and all PR-caused CI failures on head 31839bd.

CCR review 5434470410, posted 2026-10-06T20:55:21Z, has one inline comment:

  • src/Components/JSInterop/src/IJSRuntime.cs:25 (comment): "The registered SSR implementation, UnsupportedJavaScriptRuntime, implements these members without either (src/Components/Endpoints/src/DependencyInjection/UnsupportedJavaScriptRuntime.cs:14-35), so trimmed Razor Components apps can now report annotation-mismatch warnings even though that implementation only throws." The review body says the registered SSR runtime is not aligned with the new interface annotation contract.

CI failures attributable to this PR:

Pipeline / authoritative attempt Failed checks and steps Key error
aspnetcore-ci, build 1625511, attempt 2 Linux x64 build (Run build.sh, log 312), Windows x64/x86/arm64 build (Build x64, log 343), managed source build (Build, log 323), Ubuntu x64 test build (Run build.sh, log 330), Windows Server x64 test build (Run build.cmd, log 381), Helix subsets 1/2 (Build shared fx, logs 361/364) error IL2026: Using member 'Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime, String, params Object[])' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. Also affects InvokeAsync, IJSRuntime.InvokeAsync, and JSObjectReferenceExtensions.InvokeVoidAsync.
aspnetcore-ci, build 1625511, attempt 2 Windows local development validation (Build (Debug), log 397) error IL2046: Microsoft.AspNetCore.Components.Endpoints.UnsupportedJavaScriptRuntime.InvokeAsync<TValue>(String,CancellationToken,Object[]): Interface member ... with 'RequiresUnreferencedCodeAttribute' has an implementation member ... without 'RequiresUnreferencedCodeAttribute'. Four affected implementations, including both constructor overloads and the explicit InvokeAsync implementation. This confirms the CCR finding in CI.
aspnetcore-ci, build 1625511, attempt 2 macOS arm64/x64 builds (Run build.sh, logs 434/446) Same 16 new IL2026 build errors; exit code 1.
aspnetcore-ci, build 1625511, attempt 2 macOS test build (Run build.sh, log 458); monitor log 472; parent pipeline Same 16 new IL2026 build errors, exit code 1 before tests. Monitor reports "One or more non-monitor pipeline jobs failed." and exits 1.
aspnetcore-components-e2e, build 1625513, attempt 1 CoreCLR/Mono E2E build steps, logs 43/27; parent pipeline Same new IL2026 build errors; Bash exit code 1 before browser tests.
aspnetcore-quarantined-pr, build 1625512, attempt 1 Ubuntu/Windows/Helix build steps, logs 25/48/38; parent pipeline Same new IL2026 build errors before tests; exit code 1.
aspnetcore-template-tests-pr, build 1625514, attempt 2 Tests: Helix template tests x64 / Build shared fx, log 40; monitor log 50; parent pipeline Same new IL2026 build errors, exit code 1. Monitor reports "One or more non-monitor pipeline jobs failed."

IL2026 sites include ElementReferenceExtensions.cs:41, HeadOutlet.cs:31, FocusOnNavigate.cs:80, NavigationLock.cs:90,94,112, InputFile.cs:53,77, BrowserFileStream.cs:90, JSComponentInterop.cs:186,194, VirtualizeJsInterop.cs:110,132,160, FileDownload.cs:118, and MediaComponentBase.cs:201.

The PR build uses merge commit 45033ff4bd5363a3dae26f721ff0aaf47b83b679 with target parent 16e71d2fdda93f54bdf8941d3cd6284ba94c3847. On that exact target, build 1625094 passes the corresponding Linux/Windows/macOS builds, managed source build, Ubuntu tests, Helix subsets, and Windows local validation; E2E baseline 1625096 gets past build (CoreCLR succeeds, Mono succeeds with issues), quarantined baseline 1625095 gets past build, and template baseline 1625097 succeeds. The PR adds the annotations named by the new compiler errors.

Final check conclusions on this head: 25 FAILURE (the pipeline/job checks above, Build Analysis, and Build Insights), 4 SUCCESS (Code check, CLA, and both Helix Queue Insights checks), and 1 NEUTRAL (always-green). Build Analysis and Build Insights are aggregate failures, not additional independent product failures.

Unrelated failures: the superseded Windows Server attempt-1 log 150 and template attempt-1 log 14 were matched to dotnet/dnceng#5922, "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host." This is a transport/infrastructure failure, not caused by the annotation changes; no code change is requested for that failure. It does not explain the authoritative attempts' IL2026/IL2046 errors. Markdownlint is action_required, an approval gate, not a failed workflow; no code change is requested for that gate.

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>

Copilot AI commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please address the CCR review comment and all PR-caused CI failures on head 31839bd.

CCR review 5434470410, posted 2026-10-06T20:55:21Z, has one inline com...

Implemented in ed1a296. UnsupportedJavaScriptRuntime now matches the interface trimming contract, with a regression test for warning and generic-member annotation parity. Added narrow suppressions for the reported fixed framework serialization call sites. Endpoint and Media builds/tests pass with 0 warnings; the JSInterop annotation tests passed (12 cases). The new CI run (build 1626462) is queued, so its pipeline result is still pending.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The callback suppression can hide trimming failures for arbitrary EventCallback<T> payload object graphs.

Review effort: Balanced
Findings: 1 High severity · 1 Medium severity

Open (2)

return new(null, callback);
}

[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The callback value type is defined by the component's EventCallback<T> parameter and preserved by the component parameter contract.")]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added RequiresUnreferencedCode to all four public RegisterForJavaScript overloads and changed the callback suppression to rely on that consumer-visible registration warning, not component parameter preservation. A regression test verifies the annotations. Commit: 70f27004.

@PureWeen

PureWeen commented Oct 7, 2026

Copy link
Copy Markdown
Member

@copilot Please address the CCR review comment and all PR-caused CI failures on head ed1a296.

CCR review 5443916440, posted 2026-10-07T14:34:29Z, has one new inline comment:

  • src/Components/Web/src/JSComponents/JSComponentInterop.cs:191 (comment): "This suppression is unsafe for arbitrary EventCallback<T> payloads. RegisterForJavaScript preserves the component type with LinkerFlags.Component, but All does not transitively preserve members of a parameter property's generic argument; a trimmed app using EventCallback<MyPayload> can therefore reach the callback below and serialize a stripped MyPayload." The review body says the callback suppression can hide trimming failures for arbitrary payload object graphs. Its overview also retains the original SSR annotation finding, whose implementation mismatch was addressed in ed1a296.

PR-caused CI build errors on this head include:

error IL2026: Using member 'Microsoft.JSInterop.JSRuntimeExtensions.InvokeAsync<TValue>(IJSRuntime, String, params Object[])' which has 'RequiresUnreferencedCodeAttribute' can break functionality when trimming application code. JSON serialization and deserialization might require types that cannot be statically analyzed.

Other errors name JSObjectReferenceExtensions.InvokeAsync, JSObjectReferenceExtensions.InvokeVoidAsync, JSRuntimeExtensions.InvokeVoidAsync, and JSInProcessRuntimeExtensions.InvokeVoid.

Affected sites include QuickGrid.razor.cs:314,321,327,660; Shared PullFromJSDataStream.cs:100, ResourceCollectionProvider.cs:57,60, TransmitDataStreamToJS.cs:24,28,35; WebAssembly Authentication RemoteAuthenticationService.cs:105,127,137,159,176,202,213; and WebAssembly WebAssemblyConsoleLogger.cs:96, WebAssemblyNavigationManager.cs:71,85. They are remaining downstream errors after the Web/Media changes in ed1a296.

The PR merge source is 433735855f67368c77968803c4ea12da9d217048, with target parent bfec1097ca17f90a9733a1d98063869a10a3e818. The exact-target main CI build 1626162 succeeds; the PR-added annotations are the members identified by these new IL2026 diagnostics.

Final CI results (all attempt 1):

Pipeline Failed checks / steps Key errors
aspnetcore-ci 1626462 Linux build log 82; Windows build log 158; macOS arm64/x64 build logs 134/140; Ubuntu/macOS test build logs 120/198; Windows Server test build log 200; Helix subset build logs 177/181 Remaining IL2026 errors above; build exit 1 before tests. Windows builds also report src/BuildAfterTargetingPack/BuildAfterTargetingPack.csproj(51,5): error MSB4181: The "MSBuild" task returned false but did not log an error after the downstream build errors.
aspnetcore-ci 1626462 Windows local development validation, Build (Debug) log 226 IL2026 linker errors for the same remaining QuickGrid/Shared/WebAssembly call sites; Cmd.exe exit 1.
aspnetcore-components-e2e 1626465 CoreCLR/Mono build logs 29/27; parent pipeline Same IL2026 errors; Bash exit 1 before browser tests.
aspnetcore-quarantined-pr 1626463 Ubuntu/Windows/Helix build logs 25/48/38; parent pipeline Same IL2026 errors, Windows nested MSB4181, build exit 1 before tests.
aspnetcore-template-tests-pr 1626466 Template Helix Build shared fx log 14; monitor log 24; parent pipeline Same IL2026 errors and nested MSB4181; monitor reports "One or more non-monitor pipeline jobs failed." and Bash exit 1.
aspnetcore-ci 1626462 Monitor log 241; parent pipeline "One or more non-monitor pipeline jobs failed.", Bash exit 1. These aggregate the failed builds above.

Final conclusions: 24 FAILURE (the listed pipeline/job checks plus Build Analysis/Build Insights), 5 SUCCESS (managed source-build, Code check, CLA, both Helix Queue Insights), 1 NEUTRAL (always-green). Build Analysis/Build Insights are aggregate failures, not separate product errors.

No unrelated failure was established in these final attempt-1 logs. Markdownlint remains action_required, an approval gate rather than a CI failure; no code change is requested for that gate. The prior transport-reset known issue is not the cause of these final build errors.

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>

Copilot AI commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please address the CCR review comment and all PR-caused CI failures on head ed1a296.

CCR review 5443916440, posted 2026-10-07T14:34:29Z, has one new inline...

Committed as 70f27004. The EventCallback issue now warns at JS component registration; the reported fixed-payload call sites have narrow suppressions. QuickGrid, WebAssembly, and WebAssembly Authentication builds pass with 0 warnings; the focused JSInterop annotation tests (12), registration warning test (1), and SSR runtime annotation test (1) pass. The full CI matrix has not completed in this run.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Blazor IJSInProcessObjectReference.Invoke is attributed with RequiresUnreferencedCode

3 participants