CommunityToolkit / CommunityToolkit/dotnet

AsyncRelayCommand causes InvalidOperation_HandleIsNotInitialized crashes in .NET 10 version of MAUI

Open
#1,193 0 comments 0 reactions 0 assignees View on GitHub
bug :bug:
Dominant language
C#
Stars
3.8k
Forks
400
PR merge metrics
No merged PRs in 30d

Description

### Describe the bug

After upgrading MAUI from .NET 9 version to .NET 10 (specifically 10.0.51), random crashes are reported. I'm not able to reproduce it but the crash rate surged for both Android and Windows (I don't release for iOS/Mac).

There are 2 scenarios that causes the crash:
1. **Using any AsyncRelayCommand that prevents concurrent execution (which is the default setting)**. When the command finishes, it runs NotifyCanExecuteChanged internally. That causes IsEnabled property to a Button that uses the command to be updated and that can randomly cause the app to crash with InvalidOperation_HandleIsNotInitialized. **Workaround:** I managed to mitigate the crashes by creating the commands with AsyncRelayCommandOptions.AllowConcurrentExecutions option and preventing concurrent execution manually in my code. It added a lot of boiler plate code so I don't like the solution but it definitelly helped.

2. ** Calling NotifyCanExecuteChanged() in the code** can unfurtunatelly also crash the app. This is less frequent by the first case but it happends. My workaround was to create a helper method that calls NotifyCanExecuteChanged() on an AsyncRelayCommand but encloses the call in a try..catch block silently catching all exceptions and reporting them. Again, not a great solution, but necessary for .NET MAUI to keep the crash rate back on a .NET 9 level.

I'm not sure what was changed and if the problem is in MVVM toolkit or MAUI.

Example of the stack traces:
```
android.runtime.JavaProxyThrowable: [System.InvalidOperationException]: InvalidOperation_HandleIsNotInitialized
at System.WeakReference`1[[Microsoft.Maui.Controls.BindableObject, Microsoft.Maui.Controls, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null]].SetTarget + 0x29(Unknown Source:-1)
at Microsoft.Maui.Controls.Internals.TypedBinding`2[[System.String, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].ApplyToResolvedSource + 0x0(Unknown Source:-1)
at Microsoft.Maui.Controls.Internals.TypedBinding`2[[System.String, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Apply + 0xa8(Unknown Source:-1)
at Microsoft.Maui.Controls.BindableObject.ForceBindingApply + 0x27(Unknown Source:-1)
at Microsoft.Maui.Controls.CommandElement.GetCanExecute + 0x43(Unknown Source:-1)
at Microsoft.Maui.Controls.Button.get_IsEnabledCore + 0x8(Unknown Source:-1)
at Microsoft.Maui.Controls.VisualElement.CoerceIsEnabledProperty + 0x16(Unknown Source:-1)
at Microsoft.Maui.Controls.BindableObject.SetValueCore + 0xf7(Unknown Source:-1)
at Microsoft.Maui.Controls.BindableObject.SetValue + 0x55(Unknown Source:-1)
at Microsoft.Maui.Controls.BindableObjectExtensions.RefreshPropertyValue + 0x45(Unknown Source:-1)
at Microsoft.Maui.Controls.VisualElement.RefreshIsEnabledProperty + 0x0(Unknown Source:-1)
at Microsoft.Maui.Controls.Button.Microsoft.Maui.Controls.Internals.ICommandElement.CanExecuteChanged + 0x0(Unknown Source:-1)
at Microsoft.Maui.Controls.WeakCommandSubscription+CommandCanExecuteSubscription.CanExecuteChanged + 0x2c(Unknown Source:-1)
at Unknown.Unknown(Unknown Source:-1)
at CommunityToolkit.Mvvm.Input.AsyncRelayCommand`1+<g__MonitorTask|22_0>d[[System.String, System.Private.CoreLib, Version=10.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext + 0x111(Unknown Source:-1)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw + 0x11(Unknown Source:-1)
at System.Threading.Tasks.Task+<>c.b__124_0 + 0x0(Unknown Source:-1)
at Android.App.SyncContext+<>c__DisplayClass2_0.b__0 + 0x0(Unknown Source:-1)
at Java.Lang.Thread+RunnableImplementor.Run + 0x8(Unknown Source:-1)
at Java.Lang.IRunnableInvoker.n_Run + 0x16(Unknown Source:-1)
at mono.java.lang.RunnableImplementor.n_run(RunnableImplementor.java:-2)
at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:21)
at android.os.Handler.handleCallback(Handler.java:995)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loopOnce(Looper.java:273)
at android.os.Looper.loop(Looper.java:363)
at android.app.ActivityThread.main(ActivityThread.java:10060)
at java.lang.reflect.Method.invoke(Method.java:-2)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:632)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
```

### Regression

Not sure. It used to work in .NET 9 version of MAUI and started to crash aftter upgrading to .NET 10.

### Steps to reproduce

I cannot reproduce it locally. The AppCenter reports that the app crashes sometimes after an hour if its usage, sometimes just in a few minutes. The crashes are random but too frequent to be ignored.

### Expected behavior

No crashes as with the .NET 9 version of MAUI

### Screenshots

_No response_

### IDE and version

Other

### IDE version

VS2026 (18.5.2)

### Nuget packages

- [ ] CommunityToolkit.Common
- [ ] CommunityToolkit.Diagnostics
- [ ] CommunityToolkit.HighPerformance
- [x] CommunityToolkit.Mvvm (aka MVVM Toolkit)

### Nuget package version(s)

8.4.2

### Additional context

_No response_

### Help us help you

No, just wanted to report this

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.