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

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions