Domain knowledge for triaging and fixing .NET failures on Apple mobile (iOS, tvOS, MacCatalyst) and Android. Use when runtime-extra-platforms or mobile CI is failing, when investigating iOS, tvOS, MacCatalyst, iossimulator, tvossimulator, or Android build/test failures, or when a change touches mobile pipeline YAML, AppleAppBuilder/AndroidAppBuilder, code signing, provisioning, simulator/emulator startup, platform conditionals, or NativeAOT-on-mobile behavior. Covers failure triage (infrastructure vs code), CI pipeline structure, platform-specific code paths, and NativeAOT compilation on mobile.
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
—
The risk profile of this skill
Triage and fix .NET failures on Apple mobile (iOS, tvOS, MacCatalyst) and Android in dotnet/runtime.
Mobile platforms run .NET on devices and simulators/emulators where the host OS controls code execution. Apple forbids JIT in production (simulators allow it), requires code signing, and has six OS variants that often need identical handling. Android requires cross-compilation and APK packaging across four architectures. Both surface failures invisible on desktop: provisioning errors, emulator boot timeouts, app bundle signing, native toolchain mismatches.
CoreCLR is the primary runtime. NativeAOT is the default publish framework for ahead-of-time compilation. Mono also runs in CI alongside CoreCLR.
Mobile tests run in the runtime-extra-platforms pipeline (AzDO definition 154, org dnceng-public, project public), daily on main and on relevant PRs.
Jobs follow {platform} {config} {subset}:
| Platform | Job pattern | Variants |
|---|---|---|
| iOS Simulator | iossimulator-{x64,arm64} | CoreCLR, Mono, NativeAOT |
| tvOS | tvos_arm64 | CoreCLR, Mono, NativeAOT |
| MacCatalyst | maccatalyst-{x64,arm64} | CoreCLR, Mono, NativeAOT, AppSandbox |
| Android | android-{arm,arm64,x64,x86} | CoreCLR, Mono, NativeAOT |
Suffixes: empty (libraries), RuntimeTests, Smoke, AppSandbox, Interp.
Start from the failure type, not the platform. The tables below map failure symptoms to code paths.
These happen before tests run. The app bundle fails to build, sign, or package.
| Platform | Build targets | App builder task |
|---|---|---|
| Apple | src/mono/msbuild/apple/build/ | src/tasks/AppleAppBuilder/ |
| Android | src/mono/msbuild/android/build/ | src/tasks/AndroidAppBuilder/ |
Apple code signing uses DevTeamProvisioning: - for simulators, adhoc for MacCatalyst. If a signing error mentions provisioning profiles, check whether the right value is passed in the pipeline YAML.
The test itself fails or crashes on the device/emulator.
| Platform | Test runner | Test targets |
|---|---|---|
| Apple | src/libraries/Common/tests/AppleTestRunner/ | eng/testing/tests.ioslike.targets |
| Android | src/libraries/Common/tests/AndroidTestRunner/ | eng/testing/tests.android.targets |
Common cause: a test assumes desktop behavior (process spawning, filesystem layout, JIT availability). Check whether the test has platform-specific skip conditions using PlatformDetection.
NativeAOT on mobile has a different target resolution path than desktop. Directory.Build.targets evaluates before NuGet package targets, so properties like _IsApplePlatform from Microsoft.DotNet.ILCompiler are not available in eng/toolAot.targets. For Apple mobile library tests, ILCompilerTargetsPath must be set to $(CoreCLRBuildIntegrationDir)Microsoft.DotNet.ILCompiler.SingleEntry.targets with _IlcReferencedAsPackage=false.
Key files: eng/targetingpacks.targets, eng/toolAot.targets.
Stack traces pointing into native code or P/Invoke calls.
| Platform | Native libs |
|---|---|
| Apple | src/native/libs/System.Security.Cryptography.Native.Apple/, src/native/libs/System.Native/ios/ |
| Android | src/native/libs/ (shared with Linux/Bionic) |
When the job definition itself is wrong (e.g., missing a platform, wrong build args):
| Platform | Pipeline files |
|---|---|
| Apple (ioslike) | eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml |
| Apple (simulator) | eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml |
| Apple (maccatalyst) | eng/pipelines/extra-platforms/runtime-extra-platforms-maccatalyst.yml |
| Android | eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml |
| Android (emulator) | eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml |
Things that have caused confusion before and will again:
ios, iossimulator, tvos, tvossimulator, maccatalyst (x64 + arm64). A fix for one variant almost always needs to cover all six. Missing one causes the next pipeline run to fail on a different job.2>/dev/null does not suppress its errors; use >/dev/null 2>&1.android-arm, android-arm64, android-x64, android-x86. x86 is 32-bit and can expose different issues than the 64-bit targets.Directory.Build.targets runs before NuGet package .targets. Properties from packages are not available in eng/toolAot.targets.Classify every failure as infrastructure or code before acting.
Follow the repository's GitHub publication authorization rules for all proposed issues, updates, and comments below. In an interactive session, explicit advance permission covering the proposed publication is sufficient; do not ask again. An executing workflow's documented publication contract may also authorize the proposed publication within its currently authorized actions; follow any approval conditions it requires. Otherwise, in interactive and coding sessions, present the complete draft and obtain explicit approval before publishing. Without authorization, leave the draft locally. A workflow's authorization covers only its declared outputs and action limits, not every reporting action described in this skill.
Caused by the test environment, not code. Indicators:
Prepare an update for an existing tracking issue with a table entry:
| Build | Date | Machine | Job | Error |
|---|---|---|---|---|
| #buildNumber | YYYY-MM-DD | machineName | jobName | brief error |
If no matching issue exists, draft one with area-Infrastructure and platform labels (os-ios, os-tvos, os-maccatalyst, os-android).
For already tracked known issues, check whether the root cause is actionable. If a code or configuration fix is feasible, prepare the fix and recommend a PR; open it only when publication is authorized. If the issue is purely infrastructure (device provisioning, network), draft occurrence data for the tracking issue instead.
Caused by recent commits. Indicators:
Investigate code failures by starting with git log --oneline --since='3 days ago' on the relevant path. If nothing matches, widen the window or check for intermittent patterns across recent builds. Common patterns:
#if conditional compilation missing a mobile targetWhen a mobile fix workflow discovers new patterns or workarounds, draft a comment on the tracking issue (or a new issue labeled area-Infrastructure-mono) so the team can later incorporate it into this document. Publish only with the authorization described above. Include findings about:
Keep PRs focused on the mobile failure being fixed. Unrelated skill edits make review and blame harder, so avoid editing this file in PRs that are not fixing or documenting mobile platform work.
dotnet/runtime
1df7015
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.