-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
[wasm][AOT] Assertion at appdomain.c:188 — g_assert(string_empty_fld) fails on any AOT-compiled Blazor WASM project (.NET 10)
Description
AOT-compiled Blazor WebAssembly applications crash at runtime initialization with an assertion failure in create_domain_objects(). The crash occurs before any user code executes — the Mono runtime cannot even initialize String.Empty.
This is not an out-of-memory issue (tested with EmccInitialHeapSize up to 512 MB). The bug is reproducible across SDK 10.0.102 (runtime 10.0.2) and SDK 10.0.201 (runtime 10.0.5) with various configurations.
Error
[MONO] * Assertion at /__w/1/s/src/runtime/src/mono/mono/metadata/appdomain.c:188,
condition `<disabled>' not met
MONO_WASM: mono_wasm_load_runtime () failed
Stack trace points to create_domain_objects() → mono_class_get_field_from_name_full(mono_defaults.string_class, "Empty", NULL) returning NULL → g_assert(string_empty_fld) fails.
Reproduction
Minimal project configuration
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<RunAOTCompilation>true</RunAOTCompilation>
<WasmBuildNative>true</WasmBuildNative>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode>
</PropertyGroup>
<!-- Any non-trivial set of packages (e.g., FluentValidation, SignalR, Serilog) -->
</Project>Steps
- Create a Blazor WASM standalone app targeting
net10.0with several NuGet packages (118+ assemblies after resolution) dotnet publish -c Release- Serve the
publish/wwwrootfolder with any static file server - Open in Chrome → crash in console before the app renders
Environment
- SDK: 10.0.201
- Runtime: 10.0.5
- Workload: wasm-tools 10.0.105/10.0.100
- OS: Windows 11 (10.0.26200)
- Browser: Chrome (also tested Edge & firefox, same result)
Configurations tested
All configurations produce the same appdomain.c:188 crash unless noted:
| Configuration | dotnet.native.wasm size | WasmInitialHeapSize | Result |
|---|---|---|---|
| AOT + TrimMode=partial | 45 MB | 32 MB (default) | Crash appdomain.c:188 |
| AOT + no trim (98 MB bundle, Telerik UI) | 98 MB | 67 MB (default) | Crash appdomain.c:188 |
AOT + TrimMode=partial + EmccInitialHeapSize=536870912 (512 MB) |
45 MB | 512 MB | Crash appdomain.c:188 |
AOT + WasmDedup=false |
87 MB | 32 MB | Different crash: interp.c:4135 — should not be reached |
| SDK 10.0.102 (runtime 10.0.2) | 45 MB | 32 MB | Crash appdomain.c:188 |
| SDK 10.0.201 (runtime 10.0.5) | 45 MB | 32 MB | Crash appdomain.c:188 |
Key finding: The 512 MB heap test proves this is not an OOM issue. The runtime has 512 MB available but still cannot resolve String.Empty during create_domain_objects().
Analysis
The assertion at appdomain.c:188:
string_empty_fld = mono_class_get_field_from_name_full(
mono_defaults.string_class, "Empty", NULL);
g_assert(string_empty_fld); // <-- CRASH: returns NULLmono_class_get_field_from_name_full returns NULL for System.String.Empty — the most fundamental type in the runtime. This happens only with AOT compilation; the same project works perfectly with the Mono interpreter (no AOT).
The WasmDedup=false test bypasses this crash but reveals a second bug in interp.c:4135, suggesting deeper metadata corruption in the AOT compilation pipeline.
Without AOT (interpreter) — works fine
The same project runs correctly without AOT. Benchmark results on the Mono interpreter:
- Pure compute (10M iterations): 429 ms (vs ~5 ms native, ~20 ms AOT)
- JSON serialize/deserialize (1000x): 878 ms
This confirms the interpreter works but is ~80x slower than native — AOT is critically needed for acceptable runtime performance.
Related issues
- [wasm] [MONO] * Assertion at /__w/1/s/src/runtime/src/mono/mono/metadata/appdomain.c:188, condition `<disabled>' not met #121840 — Same assertion, closed without fix (maintainer suggested OOM, but our 512 MB test disproves this)
- Working WASM project migrated to .NET 10 - 'MONO interpreter: NIY encountered in method' or 'Your mono runtime and class libraries are out of sync' #121849 — Similar WASM AOT failures on .NET 10 migration (still open)
Expected behavior
AOT-compiled Blazor WASM apps should initialize the Mono runtime and run correctly, as they did on .NET 9.
Actual behavior
The Mono runtime crashes at the very first initialization step (String.Empty field resolution) before any user code can execute.
note: I used AI to help me generate this issue