Skip to content

[release/10.0] Detach methods when disconnection confirmed.#66347

Open
github-actions[bot] wants to merge 2 commits intorelease/10.0from
backport/pr-66275-to-release/10.0
Open

[release/10.0] Detach methods when disconnection confirmed.#66347
github-actions[bot] wants to merge 2 commits intorelease/10.0from
backport/pr-66275-to-release/10.0

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented Apr 17, 2026

Backport of #66275 to release/10.0

/cc @ilonatommy

Detach methods when disconnection confirmed.

Fix JSException "Interop methods are already registered for renderer 1" during reconnect→resume fallback.

Description

When a Blazor Server client disconnects (common on mobile), DefaultReconnectionHandler calls reconnect(). If ConnectCircuit fails (circuit expired), it falls back to resume(), which creates a new RemoteRenderer on the server. That renderer's constructor calls attachWebRendererInterop(1, newMethods) via JS interop, but reconnect() had already re-attached saved interop methods and didn't clean them up when ConnectCircuit returned false — causing the throw.

The fix adds 3 lines in CircuitManager.reconnect(): when ConnectCircuit returns false, detach the interop methods (guarded by isRendererAttached to handle edge cases where the renderer wasn't attached).

Introduced by PR #62259 ("[Blazor] Adds support for persisting and restoring disconnected circuits from storage") which added the resume() fallback after failed reconnect().

Fixes #64738

Customer Impact

Users running Blazor Server apps on .NET 10 experience unobserved JSException when mobile clients disconnect and the circuit expires on the server. The exception surfaces via TaskScheduler.UnobservedTaskException, which can crash the application if not explicitly caught.
The bug prevents the .NET 10 circuit resume feature from working - the page is left non-functional and requires a manual refresh.
Workarounds exist: catching and ignoring the exception globally (page still broken, needs refresh, state that should be preserved in such situations in .net10 is lost), or providing a custom reconnectionHandler that reloads instead of calling resume() (works correctly, equivalent to .NET 9 behavior, but forgoes the seamless resume feature and also looses the state).

Regression?

  • Yes
  • No

The bug was added in resume and persisting state PR which is a new feature in .net10. However, from user's perspective it is a regression. In .net9 disconnection and reconnection never threw an exception because resume() fallback didn't exist. Upgrading to .net10 introduces a crash.

Risk

  • High
  • Medium
  • Low

The fix code only executes in a failure path (when ConnectCircuit has already returned false == the circuit is gone on the server). It cleans up stale client-side state (a JS Map entry) that would otherwise block the subsequent resume(). The isRendererAttached guard makes it a no-op when the renderer wasn't attached. No server-side changes, no public API changes, no protocol changes.
The change cannot affect successful reconnections.

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

@github-actions github-actions Bot requested a review from a team as a code owner April 17, 2026 08:35
@ilonatommy ilonatommy self-assigned this Apr 17, 2026
@github-actions github-actions Bot added the area-blazor Includes: Blazor, Razor Components label Apr 17, 2026
@ilonatommy ilonatommy requested review from javiercn and lewing April 17, 2026 09:09
@ilonatommy ilonatommy added the Servicing-consider Shiproom approval is required for the issue label Apr 17, 2026
@ilonatommy ilonatommy added this to the 10.0.x milestone Apr 17, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Hi @github-actions[bot]. Please make sure you've updated the PR description to use the Shiproom Template. Also, make sure this PR is not marked as a draft and is ready-to-merge.

To learn more about how to prepare a servicing PR click here.

@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Looks like this PR hasn't been active for some time and the codebase could have been changed in the meantime.
To make sure no conflicting changes have occurred, please rerun validation before merging. You can do this by leaving an /azp run comment here (requires commit rights), or by simply closing and reopening.

@dotnet-policy-service dotnet-policy-service Bot added the pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun label Apr 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Includes: Blazor, Razor Components pending-ci-rerun When assigned to a PR indicates that the CI checks should be rerun Servicing-consider Shiproom approval is required for the issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant