Skip to content

Blazor DotNet.invokeMethodAsync from a web component triggers heap is currently locked error #62476

Open
@alexuaua

Description

@alexuaua

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

When attempting to call DotNet.invokeMethodAsync from a JavaScript file backing a custom Web Component during its initialization (for example, inside connectedCallback), the following error is thrown:

Error: Assertion failed - heap is currently locked
at mr (blazor.web.js:1:158963)
at Object.beginInvokeDotNetFromJS

This happens in a Blazor WebAssembly project.The same approach works fine in a .NET MAUI Blazor Hybrid app.

I'm aware that calling .NET from JS during component initialization isn't considered a good practice, but invoking .NET methods would help a gradual migration of a legacy web app to Blazor and MAUI. The goal is to integrate Blazor as a backend facade while preserving the existing UI for now, enabling the team to write new code in Blazor moving forward.
The documentation does not appear to impose any restriction that prevents from using this to handle JS calls: Link to docs.

Minimal repro repo

https://github.com/alexuaua/BlazorDotNetInteropDemo

Steps to reproduce

  1. Clone the repo.
  2. Run the project and switch to the Counter page.
  3. Open the browser console.
  4. Observe the heap is currently locked error (only) during initialization of the web component.

Expected behaviour

The JS-to-.NET interop call should succeed (as it does in MAUI Blazor), or there should be a documented workaround for such use cases. Alternatively, the documentation should clearly explain the restrictions on using DotNet.invokeMethodAsync in Blazor WebAssembly apps.

Actual behaviour

The interop call fails due to what appears to be a race condition.

Deferring the call using setTimeout (i.e. placing the call later in the stack) resolves the issue, this workaround is even shown in community resources like Blazor University.

That said, it would be very helpful if:

  • The official documentation explicitly described this race condition and recommended patterns for DotNet.invokeMethodAsync in component scenarios.
  • Blazor could provide a way to queue interop calls that are attempted during initialization - would be helpful for migration projects where modifying component logic is non-trivial.
    Unless I’m missing something, the tasks performed in the demo do not require synchronous execution. Blazor WebAssembly’s rendering engine is based on its own component lifecycle and does not track or wait for hydration of external DOM elements, such as those created by Web Components.

This issue blocks a real-world migration scenario where we cannot immediately rewrite all UI in Blazor. Any workaround or clarification on supported interop timing would be appreciated.

Related issues

Environment

  • .NET SDK: 9
  • Browser: Chrome / Edge (latest)
  • App: Blazor WebAssembly

Expected Behavior

No response

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

No response

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-blazorIncludes: Blazor, Razor Components

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions