dotnet / dotnet/aspnetcore

union keyword: NullableIntOrString with active null fails as interactive-root component parameter in WebAssembly (.NET 11 Preview 7)

Closed
#68,798 2 comments 0 reactions 1 assignee Claimed by @oroztocil View on GitHub
area-blazor
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 5h
Merged PRs (30d)
276

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Describe the bug

When a static SSR parent passes a `NullableIntOrString` union whose active `int?` case contains `null` to an interactive-root child component, the WebAssembly parameter restoration fails. The component never becomes interactive.

The same value works correctly through:
- Interactive Server
- Interactive Auto Cold (Server path)
- `PersistentComponentState` restoration in all modes including WebAssembly

The equivalent non-null nullable union (`(int?)42`) passes in all modes including WebAssembly.

This isolates the failure to the WebAssembly interactive-root component parameter restoration path specifically when the active `int?` case contains `null`.

### Expected Behavior

The interactive-root child component should activate successfully in WebAssembly with the active-null union value preserved, matching the behavior of Interactive Server.

After activation, the component should show:
- `Renderer: WebAssembly`
- `Interactive: True`
- `null (active null case)`

### Steps To Reproduce

1. Create a Blazor Web App with a Client project targeting .NET 11 Preview 7.
2. Define the union type:

```csharp
public union NullableIntOrString(int?, string);
```

3. Create a child component that accepts the union as a parameter:

```razor
@code {
[Parameter]
public NullableIntOrString Value { get; set; }
}
```

4. Create a static SSR host page (no page-level `@rendermode`) that passes the null value:

```razor
@page "/boundary-b03-wasm"

@code {
private NullableIntOrString value = (int?)null;
}
```

5. Run the application and navigate to `/boundary-b03-wasm`.
6. Observe that the component remains static and the console shows the error.

**Repro Repository:** https://github.com/MohamedFasulAshab/Union-Validation-68480

Relevant files:
- `UnionValidationApp.Client/Models/UnionModels.cs` — union declaration
- `UnionValidationApp.Client/Components/BoundaryTests/B03_NullableBoundary.razor` — child component
- `UnionValidationApp/Components/Pages/BoundaryTests/WASM/BoundaryB03WASM.razor` — WASM host page
- `UnionValidationApp/Components/Pages/BoundaryTests/Server/BoundaryB03.razor` — Server host page (passes)

### Exceptions (if any)

Browser console (WebAssembly):

```
ManagedError: AggregateException_ctor_DefaultMessage (Could not parse the parameter value for parameter 'Value' of type 'UnionValidationApp.Client.Models.NullableIntOrString' and assembly 'UnionValidationApp.Client'.)
```
**Browser screenshots:**
B03 — Interactive WebAssembly (active null fails):

Image

B03 — Interactive Auto Warm (same failure):

Image

The component remains:
- `Renderer: Static`
- `Interactive: False`

The error banner "An unhandled error has occurred" appears.

### .NET Version

11.0.100-preview.7.26381.103

### Anything else?

**Modes Affected:**
- Interactive WebAssembly
- Interactive Auto Warm (WebAssembly path)

**Modes Not Affected:**
- Interactive Server
- Interactive Auto Cold (Server path)

**Isolation Evidence:**

| Test | Value | Server | WASM |
|------|-------|--------|------|
| B03 — NullableIntOrString boundary (active null) | `(int?)null` | Pass | **Fail** |
| B04 — NullableIntOrString boundary (active non-null)| `(int?)42` | Pass | Pass |
| P02 — NullableIntOrString persisted state (active null) | `(int?)null` | Pass | Pass |

The failure is specific to the WebAssembly interactive-root parameter restoration path when the union's active case is `int?` containing `null`. Persisted-state restoration of the same value succeeds in WebAssembly, indicating the issue is in the component parameter serialization/deserialization path rather than the JSON union converter itself.

**Reproduced in:**
- Debug build
- Published Release build
- Trimmed WebAssembly client build

---

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.