Skip to content

mlaunch crashes with FormatException when device reports iOS version string containing suffix #24935

@ducoalexandre

Description

@ducoalexandre

mlaunch fails with System.FormatException when deploying to a physical device running an iOS beta version that includes a suffix in the version string (e.g., 26.3.1 (a)).

The root cause is IRealDevice.GetProductVersion() (IDevice.cs:46) calling System.Version.Parse() on the raw version string. System.Version only accepts numeric components (major.minor[.build[.revision]]), so the (a) suffix causes the parser to fail when trying to parse "1 (a)" as an integer.

Steps to Reproduce
Connect a physical iPhone running an iOS beta build that reports a version with a suffix (in my case, 26.3.1 (a))
Build and deploy a .NET MAUI app targeting net10.0-ios
mlaunch is invoked and crashes before reaching the deployment phase
The device version can be verified with:

xcrun devicectl device info details --device -j /tmp/device_info.json

Which returns "osVersionNumber": "26.3.1 (a)".

Error Output

error MT0000: Unexpected error - Please file a bug report at https://github.com/xamarin/xamarin-macios/issues/new
System.FormatException: The input string '1 (a)' was not in a correct format.
   at System.Number.ThrowFormatException[TChar](ReadOnlySpan`1)
   at System.Number.ThrowOverflowOrFormatException[TChar,TInteger](ParsingStatus, ReadOnlySpan`1)
   at System.Number.ParseBinaryInteger[TChar,TInteger](ReadOnlySpan`1, NumberStyles, IFormatProvider)
   at System.Int32.Parse(ReadOnlySpan`1, NumberStyles, IFormatProvider)
   at System.Version.TryParseComponent(ReadOnlySpan`1, String, Boolean, Int32&)
   at System.Version.ParseVersion(ReadOnlySpan`1, Boolean)
   at System.Version.Parse(String)
   at Xamarin.Hosting.IRealDevice.GetProductVersion() in /Users/builder/azdo/_work/5/s/src/Xamarin.Hosting/Xamarin.Hosting/IDevice.cs:line 46
   at Xamarin.Hosting.IRealDevice.get_SupportsDeviceCtl() in /Users/builder/azdo/_work/5/s/src/Xamarin.Hosting/Xamarin.Hosting/IDevice.cs:line 60
   at Xamarin.Launcher.Driver.LaunchOrDebugAsync(Action, IRealDevice) in /Users/builder/azdo/_work/5/s/src/Xamarin.Hosting/Xamarin.Launcher/Main.cs:line 575
   at Xamarin.Launcher.Driver.LaunchOrDebugAsync(Action) in /Users/builder/azdo/_work/5/s/src/Xamarin.Hosting/Xamarin.Launcher/Main.cs:line 569
   at Xamarin.Launcher.Driver.MainAsync() in /Users/builder/azdo/_work/5/s/src/Xamarin.Hosting/Xamarin.Launcher/Main.cs:line 507
   at Xamarin.Utils.NSRunLoopExtensions.RunUntilTaskCompletion[T](NSRunLoop, Task`1) in /Users/builder/azdo/_work/5/s/src/Xamarin.Hosting/Xamarin.Utils/Extensions.cs:line 29
   at Xamarin.Launcher.Driver.Main2(String[]) in /Users/builder/azdo/_work/5/s/src/Xamarin.Hosting/Xamarin.Launcher/Main.cs:line 456
   at Xamarin.Launcher.Driver.Main(String[]) in /Users/builder/azdo/_work/5/s/src/Xamarin.Hosting/Xamarin.Launcher/Main.cs:line 128

Environment
Device: iPhone 16 Pro Max (iPhone17,2)
iOS version: 26.3.1 (a) (build 23D771330a)
.NET SDK: 10.0.200
iOS SDK pack: Microsoft.iOS.Sdk.net10.0_26.2 (26.2.10217)
Xcode: 26.2.0
macOS: Darwin 25.2.0 (arm64)
Suggested Fix
GetProductVersion() should strip or ignore any non-numeric suffix before calling Version.Parse(). For example, applying a regex like Regex.Replace(versionString, @"\s*(.*)$", "") to sanitize the input would handle beta suffixes gracefully.

Workaround
Deploying via xcrun devicectl bypasses mlaunch entirely and works correctly:

xcrun devicectl device install app --device <device-uuid> path/to/App.app
xcrun devicectl device process launch --device <device-uuid> com.bundle.identifier

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions