Skip to content

[.NET10] TypeError: Module.preRun.indexOf is not a function when using --preload-file via WasmShellExtraEmccFlags in browser-wasm #994

@clairernovotny

Description

@clairernovotny

Current behavior 🐛

Summary

When a Uno app targets net10.0-browserwasm and preloads a file with:

<WasmShellExtraEmccFlags Include="--preload-file <src>@/home/web_user/.nuget/NuGet/NuGet.Config" />

the app crashes at startup with:

TypeError: Module.preRun.indexOf is not a function

It occurs only when a preload bundle is present.

Affected

  • Uno.Wasm bootstrap flow with WasmShellExtraEmccFlags --preload-file

  • .NET: 10.0.0-rc.2.25502.107

  • SDK packs from build log:

    • Microsoft.NET.Runtime.WebAssembly.Sdk/10.0.0-rc.2.25502.107
    • Microsoft.NETCore.App.Runtime.Mono.browser-wasm/10.0.0-rc.2.25502.107
  • Platform: Windows (building), browser runtime (repro in local dev server)

Environment

  • Project: Uno single-project net10.0-browserwasm
  • Build shows emcc invoked via _BrowserWasmLinkDotNet
  • Preload flag used to mount a default NuGet.Config into /home/web_user/.nuget/NuGet/NuGet.Config

Reproduction steps

  1. Add a file to the project, e.g. Platforms/WebAssembly/WasmAssets/NuGet.Config.

  2. Normalize the source path to forward slashes (Windows):

    <PropertyGroup Condition="'$(TargetFramework)'=='net10.0-browserwasm'">
      <UnixProjDir>$([System.String]::Copy('$(MSBuildProjectDirectory)').Replace('\','/'))</UnixProjDir>
    </PropertyGroup>
    
    <ItemGroup Condition="'$(TargetFramework)'=='net10.0-browserwasm'">
      <WasmShellExtraEmccFlags Include="--preload-file $(UnixProjDir)/Platforms/WebAssembly/WasmAssets/NuGet.Config@/home/web_user/.nuget/NuGet/NuGet.Config" />
    </ItemGroup>
  3. Build and run the browser-wasm target.

  4. Observe startup crash.

Actual result

App fails at startup:

TypeError: Module.preRun.indexOf is not a function
 at _framework/dotnet.native.*.js

Expected behavior 🎯

Expected result

App should start normally and the preloaded file should be available at the mounted path.

Logs / traces

  • Console:

    TypeError: Module.preRun.indexOf is not a function
    at _framework/dotnet.native.XXXXXXXX.js:240:28
    at Array.forEach
    at _framework/dotnet.native.XXXXXXXX.js:239:25
    at ut (_framework/dotnet.js:4:33132)
    
  • Build shows file_packager consuming the --preload-file arg and generating a data bundle.

How to reproduce it (as minimally and precisely as possible) 🔬

Notes

  • Problem only occurs when a preload bundle exists. Without --preload-file, startup succeeds.
  • The emscripten-generated preload loader uses Module.preRun.push(...). In this scenario Module.preRun is not an array at the time it runs.
  • No explicit window.Module = {...} assignment in app code that sets preRun to a non-array. Order appears to make the preload snippet execute before Module shape is guaranteed.

Workarounds

  • Guard Module before _framework scripts load (works reliably):

    <!-- index.html BEFORE _framework/dotnet.js and uno-bootstrap.js -->
    <script>
      (function () {
        var m = (window.Module = window.Module || {});
        if (!Array.isArray(m.preRun))  m.preRun  = (typeof m.preRun  === "function") ? [m.preRun]  : [];
        if (!Array.isArray(m.postRun)) m.postRun = (typeof m.postRun === "function") ? [m.postRun] : [];
        if (!Array.isArray(m.preInit)) m.preInit = (typeof m.preInit === "function") ? [m.preInit] : [];
      })();
    </script>
  • Alternatively, inject the same guard via:

    <ItemGroup Condition="'$(TargetFramework)'=='net10.0-browserwasm'">
      <WasmShellJSFile Include="Platforms/WebAssembly/pre-run-guard.js" />
    </ItemGroup>

    ensuring it runs before the preload bundle initialization.

Suspected cause

The preload data bundle’s auto-injected loader assumes Module.preRun is an array. In Uno’s current bootstrap order for browser-wasm, that code can execute before Module is shaped, leading to .indexOf on a non-array. This only surfaces when a preload bundle exists.

Requests

  • Ensure the bootstrapper initializes Module with preRun/postRun/preInit arrays before any emscripten preload loader runs.
  • Alternatively, document that apps using WasmShellExtraEmccFlags --preload-file must initialize Module.preRun early (with a sample).

Minimal attachment

If helpful, I can attach a minimal repro with:

  • index.html
  • pre-run-guard.js (commented out to show failure)
  • .csproj using the --preload-file flag and forward-slash normalization.

Workaround 🛠️

No response

Renderer 🎨

  • Skia
  • Native

Affected platforms 📱💻🖥️

No response

Uno.Sdk version (and other relevant versions) 📦

6.4

IDE version 🧑‍💻

No response

Anything else we need to know? 💬

No response

Metadata

Metadata

Labels

No labels
No labels

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions