Skip to content

[mono][wasm] Versioned SupportedOSPlatform filters valid browser P/Invokes #132297

Description

@Sieluna

Description

Publishing a browser WebAssembly app that references a net11.0-browser
class library with P/Invokes regressed between .NET 11 preview 6 and
preview 7.

The publish succeeds without a diagnostic in both versions. With preview 7,
the generated pinvoke-table.h silently omits the library's valid browser
P/Invokes. Calling one at runtime then throws
System.EntryPointNotFoundException.

Reproduction

Minimal repository:

https://github.com/Sieluna/dotnet-wasm-pinvoke-platform-repro

dotnet-wasm-pinvoke-platform-repro-main.zip

Run:

bash ./repro.sh

The script installs both exact SDKs and matching wasm-tools workloads,
publishes the same project with isolated Emscripten caches, and checks the
generated tables.

Successful Linux CI run:

https://github.com/Sieluna/dotnet-wasm-pinvoke-platform-repro/actions/runs/31757943237

The run uploads both generated tables in the pinvoke-tables artifact.

Results

SDK Emscripten workload emscripten_get_now
11.0.100-preview.6.26359.118 5.0.6 Present
11.0.100-preview.7.26381.103 6.0.2 Missing

Preview 6 generates:

double emscripten_get_now();

static PinvokeImport __Internal_imports[] = {
    {"emscripten_get_now", emscripten_get_now},
};

Preview 7 generates an empty module:

static PinvokeImport __Internal_imports[] = {
};

{"__Internal", __Internal_imports, 0},

The class library is referenced through ProjectReference, so NuGet asset
selection is not involved.

Expected behavior

A versioned platform attribute such as
SupportedOSPlatform("browser1.0") should match the browser target.
The P/Invoke should be included in the generated table.

Root cause analysis

A normal net11.0-browser class library receives these generated assembly
attributes:

TargetPlatform("browser1.0")
SupportedOSPlatform("browser1.0")

The browser WebAssembly SDK passes TargetOS=browser.

PR #131022 added platform filtering to the Mono P/Invoke collector:

#131022

The current collector compares the complete attribute string with
_targetOS using exact equality:

https://github.com/dotnet/runtime/blob/main/src/tasks/WasmAppBuilder/mono/PInvokeCollector.cs

Therefore browser1.0 != browser. Because a
SupportedOSPlatformAttribute is present but no exact target string is
found, the assembly is treated as unsupported and all its P/Invokes are
skipped.

The comparison should use platform-name/version semantics rather than raw
string equality. A regression test using
SupportedOSPlatform("browser1.0") would cover the standard generated
attribute for net11.0-browser libraries.

Workaround

Setting this on the class library changes the generated support attribute to
SupportedOSPlatform("browser") and restores the P/Invoke:

<SupportedOSPlatformVersion>0.0</SupportedOSPlatformVersion>

This should not be required for a standard net11.0-browser class library.

Tested environments

  • Windows 11, local publish
  • ubuntu-latest, GitHub Actions
  • Mono browser WebAssembly backend

Activity

  1. added 2 commits that reference this issue on Aug 14, 2026
    b47c7f3
    25f2a3f
  2. dotnet-policy-service commented on Aug 14, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
    See info in area-owners.md if you want to be subscribed.

  3. added a commit that references this issue on Aug 14, 2026
    ec30ac0
  4. locked and limited conversation to collaborators on Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions