{"record":{"id":"d15c8bfd42a02e19","repo":"dotnet/maui","slug":"error-running-ui-tests-with-nativeaot-is-only-sup","errorCode":null,"errorMessage":"Error: Running UI tests with NativeAOT is only supported in Release configuration","messagePattern":"Error: Running UI tests with NativeAOT is only supported in Release configuration","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"eng/devices/ios.cake","lineNumber":276,"sourceCode":"\n\tInformation(\"Run UITests project {0}\", project);\n\tRunTestWithLocalDotNet(project, config, pathDotnet: toolPath, noBuild: true, resultsFileNameWithoutExtension: resultsFileName);\n\tInformation(\"UI Tests completed.\");\n}\n\nvoid ExecuteBuildUITestApp(string appProject, string device, string binDir, string config, string tfm, string rid, string toolPath)\n{\n\tInformation($\"Building UI Test app: {appProject}\");\n\tInformation($\"USE_NATIVE_AOT: {USE_NATIVE_AOT}\");\n\n\tvar projectName = System.IO.Path.GetFileNameWithoutExtension(appProject);\n\tvar binlog = $\"{binDir}/{projectName}-{config}-ios.binlog\";\n\n\tif (USE_NATIVE_AOT && config.Equals(\"Debug\", StringComparison.OrdinalIgnoreCase))\n\t{\n\t\tvar errMsg = $\"Error: Running UI tests with NativeAOT is only supported in Release configuration\";\n\t\tError(errMsg);\n\t\tthrow new Exception(errMsg);\n\t}\n\n\n\tDotNetBuild(appProject, new DotNetBuildSettings\n\t{\n\t\tConfiguration = config,\n\t\tFramework = tfm,\n\t\tToolPath = toolPath,\n\t\tArgumentCustomization = args =>\n\t\t{\n\t\t\targs\n\t\t\t.Append(\"/p:BuildIpa=true\")\n\t\t\t.Append($\"/p:_UseNativeAot={USE_NATIVE_AOT}\")\n\t\t\t.Append($\"/p:RuntimeIdentifier={rid}\")\n\t\t\t.Append(\"/bl:\" + binlog)\n\t\t\t.Append(\"/tl\");\n\n\t\t\treturn args;","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/eng/devices/ios.cake#L258-L294","documentation":"Thrown in ExecuteBuildUITestApp as a hard guard: USE_NATIVE_AOT is enabled but the requested configuration is Debug. NativeAOT requires Release (NativeAOT does not support the Debug JIT profile and the publish path is Release-only), so this is an intentional configuration rejection before invoking DotNetBuild.","triggerScenarios":"Passing --configuration=Debug (or leaving the default Debug) while USE_NATIVE_AOT=true; a CI matrix leg that sets RUNTIME_VARIANT=nativeaot but forgets to flip configuration to Release; combining a Debug device-test config with the NativeAOT runtime variant.","commonSituations":"Copy-pasting a Debug test invocation and adding a NativeAOT flag; CI template that defaults CONFIGURATION to Debug; local developer testing NativeAOT behavior without changing config.","solutions":["Set --configuration=Release (or -c Release) when running with USE_NATIVE_AOT enabled.","If you need a debuggable build, disable USE_NATIVE_AOT rather than forcing Debug.","In CI, derive configuration from the runtime variant so NativeAOT legs always use Release."],"exampleFix":"// before\nif (USE_NATIVE_AOT && config.Equals(\"Debug\", StringComparison.OrdinalIgnoreCase))\n{\n    var errMsg = $\"Error: Running UI tests with NativeAOT is only supported in Release configuration\";\n    Error(errMsg); throw new Exception(errMsg);\n}\n\n// after — normalize the config and warn instead of throwing when the intent is clear\nif (USE_NATIVE_AOT && config.Equals(\"Debug\", StringComparison.OrdinalIgnoreCase))\n{\n    config = \"Release\";\n    Warning($\"USE_NATIVE_AOT forces Release configuration; continuing with -c {config}.\");\n}","handlingStrategy":"validation","validationCode":"// Reject NativeAOT+Debug before invoking the build\nif (USE_NATIVE_AOT && config.Equals(\"Debug\", StringComparison.OrdinalIgnoreCase))\n    throw new Exception(\"NativeAOT requires Release configuration; pass -c Release or disable USE_NATIVE_AOT.\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive configuration from the runtime variant in CI so NativeAOT legs always use Release.","Default to Release when USE_NATIVE_AOT is set rather than relying on the caller to remember.","Document the NativeAOT/Release coupling wherever runtime variants are configured."],"tags":["cake","ios","nativeaot","configuration","build"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}