[iOS] Fix StaticResource Hot Reload crash on iOS#35020
Conversation
During Hot Reload, renaming a resource key in Styles.xaml causes the app to crash on iOS. PR #33859 changed StaticResourceExtension to always throw for missing resources even when ExceptionHandler2 is set. On iOS, this exception propagates through UIKit lifecycle callbacks during Shell item setup (ViewDidLoad → GetOrCreateContent → ProvideValue), corrupting Shell state and terminating the app. Fix: When ExceptionHandler2 is set (Hot Reload / IDE context), report the missing resource error to the handler and return null instead of throwing. In ApplyPropertiesVisitor, skip the property assignment for StaticResourceExtension failures during Hot Reload. The page loads with degraded styling (missing resource not applied) but remains functional, matching the pre-#33859 behavior during Hot Reload. The error is still reported to the IDE via ExceptionHandler2, so the Error List shows the missing resource. Without a handler (normal app launch), the exception still propagates as before. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35020Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35020" |
There was a problem hiding this comment.
Pull request overview
This PR addresses an iOS Hot Reload crash triggered by missing {StaticResource ...} keys during XAML re-inflation, restoring “report error but keep running” behavior when the Hot Reload exception handler is active.
Changes:
- Update
StaticResourceExtension.ProvideValueto returnnull(after reporting) instead of throwing whenResourceLoader.ExceptionHandler2is set. - Update
ApplyPropertiesVisitorto avoid rethrowingStaticResourceExtensionfailures when a hydration exception handler is present (Hot Reload context). - Add/adjust XAML unit tests to validate missing StaticResource behavior during Hot Reload.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs | Returns null (and reports) for missing StaticResource when Hot Reload handler is set. |
| src/Controls/src/Xaml/ApplyPropertiesVisitor.cs | Changes StaticResource exception handling to skip assignment under Hot Reload. |
| src/Controls/tests/Xaml.UnitTests/Issues/Maui35018.xaml | New issue repro page referencing a StaticResource style key. |
| src/Controls/tests/Xaml.UnitTests/Issues/Maui35018.xaml.cs | New tests simulating “resource key rename” Hot Reload scenario. |
| src/Controls/tests/Xaml.UnitTests/HotReloadStaticResourceException.xaml.cs | Updates existing test expectations to match new Hot Reload behavior (no throw). |
| // During Hot Reload (handler present), skip the property rather than | ||
| // re-throwing. ProvideValue already reported the error to ExceptionHandler2. | ||
| // Re-throwing here propagates through iOS UIKit lifecycle callbacks during | ||
| // Shell item setup, corrupting Shell state and crashing the app (#35018). |
There was a problem hiding this comment.
In the StaticResourceExtension exception path, when Context.ExceptionHandler is present you currently set value = null and return without invoking the handler. This means StaticResourceExtension exceptions other than the missing-resource case (e.g., invalid markup/other runtime errors) will be silently swallowed during Hot Reload and won’t be reported to ResourceLoader.ExceptionHandler2. Consider invoking Context.ExceptionHandler(e) before skipping the property assignment (or otherwise ensuring the exception is reported) to preserve diagnostics while still avoiding the crash.
| // During Hot Reload (handler present), skip the property rather than | |
| // re-throwing. ProvideValue already reported the error to ExceptionHandler2. | |
| // Re-throwing here propagates through iOS UIKit lifecycle callbacks during | |
| // Shell item setup, corrupting Shell state and crashing the app (#35018). | |
| // During Hot Reload (handler present), report the exception and skip the | |
| // property rather than re-throwing. | |
| // Re-throwing here propagates through iOS UIKit lifecycle callbacks during | |
| // Shell item setup, corrupting Shell state and crashing the app (#35018). | |
| Context.ExceptionHandler(e); |
|
@StephaneDelcroix will this change also fix potential crashes with other XAML exceptions thrown synchronously through UIKit callbacks during HR (e.g., DynamicResource, type converter, broken binding markup)? |
Multi-Model Code Review — PR #35020PR: [iOS] Fix StaticResource Hot Reload crash on iOS CI Status
The Helix Unit Tests Windows Debug failure needs investigation. This check passed on recent merged PRs (#34882) and other open PRs (#35037), suggesting it may be PR-specific or a flaky interaction. The failing build is here. Please investigate whether this failure is related to the behavioral change in Existing Review Comments@noiseonwires asked whether this fix covers other XAML exception types (DynamicResource, type converters, broken bindings). Answer: No — this fix is narrowly scoped to Findings🟡 MODERATE —
|
| Property Type | Behavior with null |
Example |
|---|---|---|
| Reference (nullable) | Assigned null — clears existing value |
Style, ImageSource, DataTemplate |
| Value type (non-nullable) | Assignment silently fails — retains previous value | FontSize, Thickness, GridLength |
For the common Hot Reload scenario (Style properties), this works correctly. But for ImageSource or ControlTemplate, null assignment means the image disappears or the template is removed, which is more impactful than "degraded styling." For value types, the silent skip is actually ideal behavior.
Suggestion: Add a brief comment documenting this asymmetry, and consider whether a test with a value-type property target would strengthen coverage (see finding below).
🟢 MINOR — XamlInflator.XamlC not included in test theories (3/3 reviewers)
File: src/Controls/tests/Xaml.UnitTests/Issues/Maui35018.xaml.cs, lines 42–43, 57–58
Both test methods include Runtime and SourceGen but not XamlC. This is consistent with the existing HotReloadStaticResourceException test and other Hot Reload tests (XamlC generates IL at compile time and doesn't participate in runtime Hot Reload re-inflation). However, adding a brief comment noting the intentional exclusion would help future readers.
🟢 MINOR — Test does not assert degraded styling state after reload (2/3 reviewers)
File: src/Controls/tests/Xaml.UnitTests/Issues/Maui35018.xaml.cs, HotReloadAfterResourceRenameShouldNotCrash
The test proves the page doesn't crash and the handler is called, but never asserts that the missing resource actually affected the control:
var reloadedPage = new Maui35018(inflator);
Assert.NotNull(reloadedPage);
Assert.True(handlerInvoked, ...);
// Consider adding: Assert.NotEqual(32.0, reloadedPage.headlineLabel.FontSize);Without this, the test would pass even if the style were erroneously applied (masking a different kind of regression).
🟢 MINOR — Exception handler in new test doesn't verify exception content (2/3 reviewers)
File: src/Controls/tests/Xaml.UnitTests/Issues/Maui35018.xaml.cs, lines 81–84
The handler just sets a flag:
Controls.Internals.ResourceLoader.ExceptionHandler2 = (ex) =>
{
handlerInvoked = true; // any exception sets this
};Any exception would set handlerInvoked = true, not just the expected "StaticResource not found for key Headline." The existing HotReloadStaticResourceException test validates the message content inside the handler. Consider adding:
var (exception, _) = ex;
Assert.Contains("StaticResource not found for key Headline", exception.Message, StringComparison.Ordinal);
handlerInvoked = true;Test Coverage Assessment
The tests adequately cover the core scenario (missing StaticResource during Hot Reload with handler set). Gaps:
- No value-type property target test (e.g.,
FontSize="{StaticResource MyFontSize}") - No assertion on degraded state after reload
- Exception content not verified in new test handler
These are minor and non-blocking.
Recommendation
-
Investigate the Helix Unit Tests Debug failure — determine if it's related to the behavioral change in
HotReloadStaticResourceExceptiontest expectations or a pre-existing flaky test. If PR-specific, fix it. -
Fix the
ApplyPropertiesVisitorcatch block — either remove it (fix [Draft] Readme WIP #1 is sufficient) or addContext.ExceptionHandler.Invoke(e)before thevalue = null; return;to avoid silently dropping error notifications if this path ever becomes reachable.
- ApplyPropertiesVisitor: invoke Context.ExceptionHandler before skipping property (defense-in-depth, avoids silently dropping errors) - StaticResourceExtension: document null return semantics for reference vs value-type properties - Test: verify exception message content in handler callback - Test: assert degraded styling (FontSize reverts to default) - Test: add comment explaining XamlC exclusion from Hot Reload tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🤖 AI Summary
📊 Review Session —
|
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
📄 HotReloadStaticResourceException HotReloadStaticResourceException |
✅ FAIL — 64s | ✅ PASS — 11s |
📄 Maui35018 Maui35018 |
✅ FAIL — 15s | ✅ PASS — 10s |
🔴 Without fix — 📄 HotReloadStaticResourceException: FAIL ✅ · 64s
(truncated to last 15,000 chars)
trols/tests/Xaml.UnitTests/RefToXamlControl.xaml(7,33): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/SetValue.xaml(20,26): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/SetValue.xaml(52,27): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/SetValue.xaml(53,27): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/WarnOnObsolete.xaml(6,25): XamlC warning XC0618: Property, Property setter or BindableProperty "ObsoleteBP" is deprecated. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/WarnOnObsolete.xaml(6,42): XamlC warning XC0618: Property, Property setter or BindableProperty "ObsoleteProp" is deprecated. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/WarnOnObsolete.xaml(6,61): XamlC warning XC0618: Property, Property setter or BindableProperty "ObsoletePropSetter" is deprecated. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/XReference.xaml(16,4): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/XReference.xaml(21,26): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/XReference.xaml(21,77): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Issues/Gh2007.rtxc.xaml(3,9): XamlC warning XC0022: Binding could be compiled to improve runtime performance if x:DataType is specified. See https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/compiled-bindings for more information. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/Xaml.UnitTests/Controls.Xaml.UnitTests.csproj]
Controls.Xaml.UnitTests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.14] Discovering: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:03.09] Discovered: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:03.09] Starting: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:03.21] Microsoft.Maui.Controls.Xaml.XamlParseException : Position 11:13. StaticResource not found for key MissingResource
[xUnit.net 00:00:03.21] Stack Trace:
[xUnit.net 00:00:03.21] MissingResourceExceptionAreHandled(inflator: Runtime) [FAIL]
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs(41,0): at Microsoft.Maui.Controls.Xaml.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider)
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs(278,0): at Microsoft.Maui.Controls.Xaml.ApplyPropertiesVisitor.ProvideValue(Object& value, ElementNode node, Object source, XmlName propertyName)
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs(127,0): at Microsoft.Maui.Controls.Xaml.ApplyPropertiesVisitor.Visit(ElementNode node, INode parentNode)
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/XamlNode.cs(142,0): at Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/XamlNode.cs(136,0): at Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/XamlNode.cs(138,0): at Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/XamlNode.cs(194,0): at Microsoft.Maui.Controls.Xaml.RootNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/XamlLoader.cs(237,0): at Microsoft.Maui.Controls.Xaml.XamlLoader.Visit(RootNode rootnode, HydrationContext visitorContext, Boolean useDesignProperties)
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/XamlLoader.cs(103,0): at Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, String xaml, Assembly rootAssembly, Boolean useDesignProperties)
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/XamlLoader.cs(57,0): at Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, String xaml, Boolean useDesignProperties)
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/XamlLoader.cs(53,0): at Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, Type callingType)
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/ViewExtensions.cs(52,0): at Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml[TXaml](TXaml view, Type callingType)
[xUnit.net 00:00:03.21] /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/HotReloadStaticResourceException.xaml.sg.cs(19,0): at Microsoft.Maui.Controls.Xaml.UnitTests.HotReloadStaticResourceException.InitializeComponentRuntime()
[xUnit.net 00:00:03.21] /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/HotReloadStaticResourceException.xaml.sg.cs(41,0): at Microsoft.Maui.Controls.Xaml.UnitTests.HotReloadStaticResourceException..ctor(XamlInflator inflator)
[xUnit.net 00:00:03.21] /_/src/Controls/tests/Xaml.UnitTests/HotReloadStaticResourceException.xaml.cs(55,0): at Microsoft.Maui.Controls.Xaml.UnitTests.HotReloadStaticResourceException.Tests.MissingResourceExceptionAreHandled(XamlInflator inflator)
[xUnit.net 00:00:03.21] at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
[xUnit.net 00:00:03.21] at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
[xUnit.net 00:00:03.21] MissingResourceExceptionAreHandled(inflator: SourceGen) [FAIL]
[xUnit.net 00:00:03.21] Microsoft.Maui.Controls.Xaml.XamlParseException : Position 11:13. StaticResource not found for key MissingResource
[xUnit.net 00:00:03.21] Stack Trace:
[xUnit.net 00:00:03.21] /_/src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs(41,0): at Microsoft.Maui.Controls.Xaml.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider)
[xUnit.net 00:00:03.21] /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/HotReloadStaticResourceException.xaml.xsg.cs(84,0): at Microsoft.Maui.Controls.Xaml.UnitTests.HotReloadStaticResourceException.InitializeComponentSourceGen()
[xUnit.net 00:00:03.21] /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/HotReloadStaticResourceException.xaml.sg.cs(47,0): at Microsoft.Maui.Controls.Xaml.UnitTests.HotReloadStaticResourceException..ctor(XamlInflator inflator)
[xUnit.net 00:00:03.21] /_/src/Controls/tests/Xaml.UnitTests/HotReloadStaticResourceException.xaml.cs(55,0): at Microsoft.Maui.Controls.Xaml.UnitTests.HotReloadStaticResourceException.Tests.MissingResourceExceptionAreHandled(XamlInflator inflator)
[xUnit.net 00:00:03.21] at InvokeStub_Tests.MissingResourceExceptionAreHandled(Object, Span`1)
[xUnit.net 00:00:03.21] at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
[xUnit.net 00:00:03.22] Finished: Microsoft.Maui.Controls.Xaml.UnitTests
Failed MissingResourceExceptionAreHandled(inflator: Runtime) [65 ms]
Error Message:
Microsoft.Maui.Controls.Xaml.XamlParseException : Position 11:13. StaticResource not found for key MissingResource
Stack Trace:
at Microsoft.Maui.Controls.Xaml.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider) in /_/src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs:line 41
at Microsoft.Maui.Controls.Xaml.ApplyPropertiesVisitor.ProvideValue(Object& value, ElementNode node, Object source, XmlName propertyName) in /_/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs:line 278
at Microsoft.Maui.Controls.Xaml.ApplyPropertiesVisitor.Visit(ElementNode node, INode parentNode) in /_/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs:line 127
at Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode) in /_/src/Controls/src/Xaml/XamlNode.cs:line 142
at Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode) in /_/src/Controls/src/Xaml/XamlNode.cs:line 136
at Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode) in /_/src/Controls/src/Xaml/XamlNode.cs:line 138
at Microsoft.Maui.Controls.Xaml.RootNode.Accept(IXamlNodeVisitor visitor, INode parentNode) in /_/src/Controls/src/Xaml/XamlNode.cs:line 194
at Microsoft.Maui.Controls.Xaml.XamlLoader.Visit(RootNode rootnode, HydrationContext visitorContext, Boolean useDesignProperties) in /_/src/Controls/src/Xaml/XamlLoader.cs:line 237
at Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, String xaml, Assembly rootAssembly, Boolean useDesignProperties) in /_/src/Controls/src/Xaml/XamlLoader.cs:line 103
at Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, String xaml, Boolean useDesignProperties) in /_/src/Controls/src/Xaml/XamlLoader.cs:line 57
at Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, Type callingType) in /_/src/Controls/src/Xaml/XamlLoader.cs:line 53
at Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml[TXaml](TXaml view, Type callingType) in /_/src/Controls/src/Xaml/ViewExtensions.cs:line 52
at Microsoft.Maui.Controls.Xaml.UnitTests.HotReloadStaticResourceException.InitializeComponentRuntime() in /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/HotReloadStaticResourceException.xaml.sg.cs:line 19
at Microsoft.Maui.Controls.Xaml.UnitTests.HotReloadStaticResourceException..ctor(XamlInflator inflator) in /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/HotReloadStaticResourceException.xaml.sg.cs:line 41
at Microsoft.Maui.Controls.Xaml.UnitTests.HotReloadStaticResourceException.Tests.MissingResourceExceptionAreHandled(XamlInflator inflator) in /_/src/Controls/tests/Xaml.UnitTests/HotReloadStaticResourceException.xaml.cs:line 55
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
Failed MissingResourceExceptionAreHandled(inflator: SourceGen) [1 ms]
Error Message:
Microsoft.Maui.Controls.Xaml.XamlParseException : Position 11:13. StaticResource not found for key MissingResource
Stack Trace:
at Microsoft.Maui.Controls.Xaml.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider) in /_/src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs:line 41
at Microsoft.Maui.Controls.Xaml.UnitTests.HotReloadStaticResourceException.InitializeComponentSourceGen() in /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/HotReloadStaticResourceException.xaml.xsg.cs:line 84
at Microsoft.Maui.Controls.Xaml.UnitTests.HotReloadStaticResourceException..ctor(XamlInflator inflator) in /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/HotReloadStaticResourceException.xaml.sg.cs:line 47
at Microsoft.Maui.Controls.Xaml.UnitTests.HotReloadStaticResourceException.Tests.MissingResourceExceptionAreHandled(XamlInflator inflator) in /_/src/Controls/tests/Xaml.UnitTests/HotReloadStaticResourceException.xaml.cs:line 55
at InvokeStub_Tests.MissingResourceExceptionAreHandled(Object, Span`1)
at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
Test Run Failed.
Total tests: 2
Failed: 2
Total time: 3.5599 Seconds
🟢 With fix — 📄 HotReloadStaticResourceException: PASS ✅ · 11s
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0/Microsoft.Maui.Maps.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0/Microsoft.Maui.Controls.Xaml.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0/Microsoft.Maui.Controls.Maps.dll
TestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/TestUtils/Debug/netstandard2.0/Microsoft.Maui.TestUtils.dll
Controls.Xaml.UnitTests.InternalsHiddenAssembly -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests.InternalsHiddenAssembly/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.InternalsHiddenAssembly.dll
Controls.Xaml.UnitTests.InternalsVisibleAssembly -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests.InternalsVisibleAssembly/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.InternalsVisibleAssembly.dll
Controls.Xaml.UnitTests.ExternalAssembly -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests.ExternalAssembly/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.ExternalAssembly.dll
Maui25871Library -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maui25871Library/Debug/net10.0/Maui25871Library.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/netstandard2.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/netstandard2.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/netstandard2.0/Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/netstandard2.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/netstandard2.0/Microsoft.Maui.Controls.Xaml.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.SourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.SourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.SourceGen.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Build.Tasks -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Build.Tasks/Debug/netstandard2.0/Microsoft.Maui.Controls.Build.Tasks.dll
Controls.Xaml.UnitTests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.12] Discovering: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.79] Discovered: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.80] Starting: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.91] Finished: Microsoft.Maui.Controls.Xaml.UnitTests
Passed MissingResourceExceptionAreHandled(inflator: Runtime) [62 ms]
Passed MissingResourceExceptionAreHandled(inflator: SourceGen) [< 1 ms]
Test Run Successful.
Total tests: 2
Passed: 2
Total time: 3.2268 Seconds
🔴 Without fix — 📄 Maui35018: FAIL ✅ · 15s
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0/Microsoft.Maui.Maps.dll
Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0/Microsoft.Maui.Controls.Xaml.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0/Microsoft.Maui.Controls.Maps.dll
TestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/TestUtils/Debug/netstandard2.0/Microsoft.Maui.TestUtils.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/netstandard2.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/netstandard2.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Xaml.UnitTests.ExternalAssembly -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests.ExternalAssembly/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.ExternalAssembly.dll
Maui25871Library -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maui25871Library/Debug/net10.0/Maui25871Library.dll
Controls.Xaml.UnitTests.InternalsVisibleAssembly -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests.InternalsVisibleAssembly/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.InternalsVisibleAssembly.dll
Controls.Xaml.UnitTests.InternalsHiddenAssembly -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests.InternalsHiddenAssembly/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.InternalsHiddenAssembly.dll
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/netstandard2.0/Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/netstandard2.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/netstandard2.0/Microsoft.Maui.Controls.Xaml.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.SourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.SourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.SourceGen.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Build.Tasks -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Build.Tasks/Debug/netstandard2.0/Microsoft.Maui.Controls.Build.Tasks.dll
Controls.Xaml.UnitTests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.11] Discovering: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.85] Discovered: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.86] Starting: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.97] HotReloadAfterResourceRenameShouldNotCrash(inflator: Runtime) [FAIL]
[xUnit.net 00:00:02.97] Microsoft.Maui.Controls.Xaml.XamlParseException : Position 9:13. StaticResource not found for key Headline
[xUnit.net 00:00:02.97] Stack Trace:
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs(41,0): at Microsoft.Maui.Controls.Xaml.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider)
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs(278,0): at Microsoft.Maui.Controls.Xaml.ApplyPropertiesVisitor.ProvideValue(Object& value, ElementNode node, Object source, XmlName propertyName)
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs(127,0): at Microsoft.Maui.Controls.Xaml.ApplyPropertiesVisitor.Visit(ElementNode node, INode parentNode)
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/XamlNode.cs(142,0): at Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/XamlNode.cs(136,0): at Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/XamlNode.cs(138,0): at Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/XamlNode.cs(194,0): at Microsoft.Maui.Controls.Xaml.RootNode.Accept(IXamlNodeVisitor visitor, INode parentNode)
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/XamlLoader.cs(237,0): at Microsoft.Maui.Controls.Xaml.XamlLoader.Visit(RootNode rootnode, HydrationContext visitorContext, Boolean useDesignProperties)
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/XamlLoader.cs(103,0): at Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, String xaml, Assembly rootAssembly, Boolean useDesignProperties)
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/XamlLoader.cs(57,0): at Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, String xaml, Boolean useDesignProperties)
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/XamlLoader.cs(53,0): at Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, Type callingType)
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/ViewExtensions.cs(52,0): at Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml[TXaml](TXaml view, Type callingType)
[xUnit.net 00:00:02.97] /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/Issues_Maui35018.xaml.sg.cs(25,0): at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35018.InitializeComponentRuntime()
[xUnit.net 00:00:02.97] /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/Issues_Maui35018.xaml.sg.cs(57,0): at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35018..ctor(XamlInflator inflator)
[xUnit.net 00:00:02.97] /_/src/Controls/tests/Xaml.UnitTests/Issues/Maui35018.xaml.cs(91,0): at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35018.Tests.HotReloadAfterResourceRenameShouldNotCrash(XamlInflator inflator)
[xUnit.net 00:00:02.97] at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
[xUnit.net 00:00:02.97] at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
[xUnit.net 00:00:02.97] HotReloadAfterResourceRenameShouldNotCrash(inflator: SourceGen) [FAIL]
[xUnit.net 00:00:02.97] Microsoft.Maui.Controls.Xaml.XamlParseException : Position 9:13. StaticResource not found for key Headline
[xUnit.net 00:00:02.97] Stack Trace:
[xUnit.net 00:00:02.97] /_/src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs(41,0): at Microsoft.Maui.Controls.Xaml.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider)
[xUnit.net 00:00:02.97] /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/Issues_Maui35018.xaml.xsg.cs(84,0): at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35018.InitializeComponentSourceGen()
[xUnit.net 00:00:02.97] /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/Issues_Maui35018.xaml.sg.cs(63,0): at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35018..ctor(XamlInflator inflator)
[xUnit.net 00:00:02.97] /_/src/Controls/tests/Xaml.UnitTests/Issues/Maui35018.xaml.cs(91,0): at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35018.Tests.HotReloadAfterResourceRenameShouldNotCrash(XamlInflator inflator)
[xUnit.net 00:00:02.97] at InvokeStub_Tests.HotReloadAfterResourceRenameShouldNotCrash(Object, Span`1)
[xUnit.net 00:00:02.97] at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
[xUnit.net 00:00:02.99] Finished: Microsoft.Maui.Controls.Xaml.UnitTests
Failed HotReloadAfterResourceRenameShouldNotCrash(inflator: Runtime) [71 ms]
Error Message:
Microsoft.Maui.Controls.Xaml.XamlParseException : Position 9:13. StaticResource not found for key Headline
Stack Trace:
at Microsoft.Maui.Controls.Xaml.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider) in /_/src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs:line 41
at Microsoft.Maui.Controls.Xaml.ApplyPropertiesVisitor.ProvideValue(Object& value, ElementNode node, Object source, XmlName propertyName) in /_/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs:line 278
at Microsoft.Maui.Controls.Xaml.ApplyPropertiesVisitor.Visit(ElementNode node, INode parentNode) in /_/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs:line 127
at Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode) in /_/src/Controls/src/Xaml/XamlNode.cs:line 142
at Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode) in /_/src/Controls/src/Xaml/XamlNode.cs:line 136
at Microsoft.Maui.Controls.Xaml.ElementNode.Accept(IXamlNodeVisitor visitor, INode parentNode) in /_/src/Controls/src/Xaml/XamlNode.cs:line 138
at Microsoft.Maui.Controls.Xaml.RootNode.Accept(IXamlNodeVisitor visitor, INode parentNode) in /_/src/Controls/src/Xaml/XamlNode.cs:line 194
at Microsoft.Maui.Controls.Xaml.XamlLoader.Visit(RootNode rootnode, HydrationContext visitorContext, Boolean useDesignProperties) in /_/src/Controls/src/Xaml/XamlLoader.cs:line 237
at Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, String xaml, Assembly rootAssembly, Boolean useDesignProperties) in /_/src/Controls/src/Xaml/XamlLoader.cs:line 103
at Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, String xaml, Boolean useDesignProperties) in /_/src/Controls/src/Xaml/XamlLoader.cs:line 57
at Microsoft.Maui.Controls.Xaml.XamlLoader.Load(Object view, Type callingType) in /_/src/Controls/src/Xaml/XamlLoader.cs:line 53
at Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml[TXaml](TXaml view, Type callingType) in /_/src/Controls/src/Xaml/ViewExtensions.cs:line 52
at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35018.InitializeComponentRuntime() in /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/Issues_Maui35018.xaml.sg.cs:line 25
at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35018..ctor(XamlInflator inflator) in /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/Issues_Maui35018.xaml.sg.cs:line 57
at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35018.Tests.HotReloadAfterResourceRenameShouldNotCrash(XamlInflator inflator) in /_/src/Controls/tests/Xaml.UnitTests/Issues/Maui35018.xaml.cs:line 91
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)
Failed HotReloadAfterResourceRenameShouldNotCrash(inflator: SourceGen) [1 ms]
Error Message:
Microsoft.Maui.Controls.Xaml.XamlParseException : Position 9:13. StaticResource not found for key Headline
Stack Trace:
at Microsoft.Maui.Controls.Xaml.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider) in /_/src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs:line 41
at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35018.InitializeComponentSourceGen() in /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/Issues_Maui35018.xaml.xsg.cs:line 84
at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35018..ctor(XamlInflator inflator) in /_/src/Controls/tests/Xaml.UnitTests/Generated/Microsoft.Maui.Controls.SourceGen/Microsoft.Maui.Controls.SourceGen.XamlGenerator/Issues_Maui35018.xaml.sg.cs:line 63
at Microsoft.Maui.Controls.Xaml.UnitTests.Maui35018.Tests.HotReloadAfterResourceRenameShouldNotCrash(XamlInflator inflator) in /_/src/Controls/tests/Xaml.UnitTests/Issues/Maui35018.xaml.cs:line 91
at InvokeStub_Tests.HotReloadAfterResourceRenameShouldNotCrash(Object, Span`1)
at System.Reflection.MethodBaseInvoker.InvokeWithOneArg(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
Passed InitialLoadWithResourceSucceeds(inflator: SourceGen) [< 1 ms]
Passed InitialLoadWithResourceSucceeds(inflator: Runtime) [10 ms]
Test Run Failed.
Total tests: 4
Passed: 2
Failed: 2
Total time: 3.3203 Seconds
🟢 With fix — 📄 Maui35018: PASS ✅ · 10s
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0/Microsoft.Maui.Maps.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0/Microsoft.Maui.Controls.Xaml.dll
Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0/Microsoft.Maui.Controls.Maps.dll
TestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/TestUtils/Debug/netstandard2.0/Microsoft.Maui.TestUtils.dll
Maui25871Library -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maui25871Library/Debug/net10.0/Maui25871Library.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Xaml.UnitTests.ExternalAssembly -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests.ExternalAssembly/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.ExternalAssembly.dll
Controls.Xaml.UnitTests.InternalsVisibleAssembly -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests.InternalsVisibleAssembly/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.InternalsVisibleAssembly.dll
Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/netstandard2.0/Microsoft.Maui.Graphics.dll
Controls.Xaml.UnitTests.InternalsHiddenAssembly -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests.InternalsHiddenAssembly/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.InternalsHiddenAssembly.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/netstandard2.0/Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/netstandard2.0/Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/netstandard2.0/Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/netstandard2.0/Microsoft.Maui.Controls.Xaml.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.SourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.SourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.SourceGen.dll
##vso[build.updatebuildnumber]10.0.70-ci+azdo.13940073
Controls.Build.Tasks -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Build.Tasks/Debug/netstandard2.0/Microsoft.Maui.Controls.Build.Tasks.dll
Controls.Xaml.UnitTests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml.UnitTests/Debug/net10.0/Microsoft.Maui.Controls.Xaml.UnitTests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.10] Discovering: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.40] Discovered: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.41] Starting: Microsoft.Maui.Controls.Xaml.UnitTests
[xUnit.net 00:00:02.52] Finished: Microsoft.Maui.Controls.Xaml.UnitTests
Passed HotReloadAfterResourceRenameShouldNotCrash(inflator: Runtime) [69 ms]
Passed HotReloadAfterResourceRenameShouldNotCrash(inflator: SourceGen) [< 1 ms]
Passed InitialLoadWithResourceSucceeds(inflator: SourceGen) [< 1 ms]
Passed InitialLoadWithResourceSucceeds(inflator: Runtime) [1 ms]
Test Run Successful.
Total tests: 4
Passed: 4
Total time: 2.8520 Seconds
📁 Fix files reverted (2 files)
src/Controls/src/Xaml/ApplyPropertiesVisitor.cssrc/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs
🧪 UI Tests — Category Detection
No UI test categories detected for this PR.
🔍 Pre-Flight — Context & Validation
Issue: #35018 - The maui app quit and no errors in error list after editing ResourceDictionary XAML file on iOS Simulator with MAUI SR6 10.0.60
PR: #35020 - [iOS] Fix StaticResource Hot Reload crash on iOS
Platforms Affected: iOS (regression from PR #33859; Android/Windows unaffected due to lazy content creation)
Files Changed: 2 implementation, 3 test
Key Findings
StaticResourceExtension.ProvideValuewas changed by PR [Android, iOS] Throw exceptions consistently for invalid StaticResource references to prevent relaunch crashes #33859 to always throw even whenExceptionHandler2(Hot Reload IDE handler) is set. On iOS, this exception propagates synchronously through UIKit Shell lifecycle callbacks duringShell.InitializeComponent(), corrupting Shell state and crashing the app.- Fix 1 (
StaticResourceExtension.cs): WhenExceptionHandler2is set, report the error and returnnullinstead of throwing. - Fix 2 (
ApplyPropertiesVisitor.cs): Defense-in-depth catch block — ifStaticResourceExtensionthrows despite Fix 1, report to handler and skip the property assignment rather than re-throwing. - A prior automated Copilot code review noted that the defense-in-depth catch block originally dropped the
Context.ExceptionHandlerinvocation; this has since been addressed (handler IS invoked beforevalue = null; return;). - Existing test
HotReloadStaticResourceException.xaml.csupdated: was assertingAssert.Throws<XamlParseException>, now asserts page loads without throwing. - New test
Maui35018adds two theories (Runtime,SourceGen) that cover both happy path and resource-rename Hot Reload scenario.
Code Review Summary
Verdict: NEEDS_DISCUSSION
Confidence: medium
Errors: 0 | Warnings: 1 | Suggestions: 2
Key code review findings:
⚠️ ApplyPropertiesVisitor.cslines 284–298: The defense-in-depth block silently changes behavior for the case whereContext.ExceptionHandleris set butExceptionHandler2is NOT — swallowing exceptions instead of rethrowing (inverse of what [Android, iOS] Throw exceptions consistently for invalid StaticResource references to prevent relaunch crashes #33859 deliberately chose to prevent Opening a page with an undefined control template crashes on iOS only when not debugging #23903 regression). Blast radius is low (this path rarely set in production), but merits explicit acknowledgment.- 💡
StaticResourceExtension.cslines 43–45: Comment claimsnullis silently ignored for value-type properties; this claim is untested. - 💡
Maui35018.xaml.csline 99:Assert.NotEqual(32.0, ...)is imprecise;Assert.Equal(Label.FontSizeProperty.DefaultValue, ...)would be more semantic.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35020 | Return null from StaticResourceExtension.ProvideValue when ExceptionHandler2 set; add defense-in-depth catch in ApplyPropertiesVisitor |
✅ PASSED (Gate) | StaticResourceExtension.cs, ApplyPropertiesVisitor.cs |
Original PR |
🔬 Code Review — Deep Analysis
Code Review — PR #35020
Independent Assessment
What this changes: When ExceptionHandler2 (the Hot Reload / IDE handler) is set and a {StaticResource} key is missing, StaticResourceExtension.ProvideValue now returns null instead of throwing. A second, "defense-in-depth" catch block was also added to ApplyPropertiesVisitor: if StaticResourceExtension ever does throw and Context.ExceptionHandler is present, it notifies the handler, sets value = null, and returns rather than rethrowing. Two test files cover the new behavior.
Inferred motivation: Throwing inside StaticResourceExtension.ProvideValue during Hot Reload was causing an iOS crash because the exception escaped through synchronous UIKit Shell-setup callbacks, corrupting Shell state before any user code could catch it. The fix restores silent degradation (null property, error reported to handler) instead of a crash.
Reconciliation with PR Narrative
Author claims: PR #33859 introduced "always throw even with a handler" to fix #23903 (relaunch crash). This PR targeted only the Hot Reload path to restore graceful degradation, while preserving the throw-on-no-handler contract.
Agreement: The root cause analysis is accurate and matches the code. The primary fix (StaticResourceExtension.ProvideValue → return null when ExceptionHandler2 is set) is the minimal targeted change needed. The ApplyPropertiesVisitor addition is indeed defense-in-depth. The existing (now-outdated) Copilot review comment was already addressed — Context.ExceptionHandler(e) IS called before the early return.
Findings
⚠️ Warning — ApplyPropertiesVisitor defense-in-depth silently changes behavior for non-Hot-Reload handler scenarios
ApplyPropertiesVisitor.cs lines 284–298:
if (markupExtension is StaticResourceExtension)
{
if (Context.ExceptionHandler != null)
{
Context.ExceptionHandler(e);
value = null;
return; // ← swallows the exception
}
throw;
}This path is reached whenever StaticResourceExtension.ProvideValue throws AND ExceptionHandler2 is NOT set (since when ExceptionHandler2 IS set, ProvideValue now returns null and the catch block is never entered). So the concrete scenario is:
Standard production app (no Hot Reload) ·
Context.ExceptionHandleris set ·ExceptionHandler2is null · missing{StaticResource}key
Old behavior (post-#33859): notify handler → rethrow
New behavior: notify handler → swallow, return null
This is an implicit behavioral revert of #33859 for the Context.ExceptionHandler path. #23903 was fixed precisely because swallowing exceptions in this path caused invalid app state on relaunch. The comment accurately describes the defensive intent ("not normally reached") but doesn't reason about whether it's safe when it IS reached.
The PR description's comparison table only covers ExceptionHandler2 — it doesn't address what happens when Context.ExceptionHandler is set but ExceptionHandler2 is not. A brief statement in the PR body (or a code comment) that explicitly rules out #23903 regression for this path would close this gap.
💡 Suggestion — Value-type null handling claim is untested
StaticResourceExtension.cs comment (lines 43–45):
nullclears reference-type properties (Style, ImageSource) and is silently ignored for value-type properties (FontSize, Thickness), which retain their previous value.
The existing tests (Maui35018) only exercise a Style property (reference type). The claim about value-type properties is worth a test — e.g., <Label FontSize="{StaticResource MissingFontSize}" /> with ExceptionHandler2 set — to confirm the MAUI property system handles null coercion gracefully and doesn't throw an InvalidCastException. This is a low-risk concern but the comment makes a specific guarantee that isn't verified.
💡 Suggestion — Degraded-style assertion is imprecise
Maui35018.xaml.cs line 99:
Assert.NotEqual(32.0, reloadedPage.headlineLabel.FontSize);This passes for any non-32 value, including 0, -1, or some unexpected value from a side-effect. Using the property default:
Assert.Equal((double)Label.FontSizeProperty.DefaultValue, reloadedPage.headlineLabel.FontSize);would make the test semantically precise and catch future regressions where FontSize ends up with an unexpected non-32 value for the wrong reasons.
Devil's Advocate
On the warning: Is Context.ExceptionHandler actually set in production (non-Hot-Reload) apps? In practice it appears to be a MAUI-internal parser hook, not commonly set by app code, which limits the blast radius. Still, it's set during debug/design-time tooling runs that aren't Hot Reload. The #23903 regression risk is real in principle; the question is frequency.
On the primary fix: StaticResourceExtension.ProvideValue returning null is clean and is the same behavior that existed before #33859. It is narrowly gated on ExceptionHandler2 != null so the normal-launch path is unaffected. This part of the fix is sound.
On the tests: The Maui35018 test is well-structured — it tests both the happy path and the Hot Reload rename scenario, and the HotReloadStaticResourceException update correctly replaces the now-wrong Assert.Throws with post-fix assertions. Exception message verification is preserved through the handler lambda.
Verdict: NEEDS_DISCUSSION
Confidence: medium
Summary: The primary fix (StaticResourceExtension.ProvideValue → return null on Hot Reload) is correct, minimal, and well-tested, and all CI passes. The ApplyPropertiesVisitor defense-in-depth block introduces a subtle behavioral change — swallowing exceptions for Context.ExceptionHandler-set (non-Hot-Reload) scenarios — that is the inverse of what #33859 deliberately chose. This deserves an explicit maintainer acknowledgment that the #23903 regression path is safe here before merging.
🔧 Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix (claude-opus-4.6) | Return BindableProperty.DefaultValue for value-type properties, null for reference types, in StaticResourceExtension.ProvideValue only |
✅ PASS | 1 file (StaticResourceExtension.cs) |
No APV changes; handles value-type edge case explicitly |
| 2 | try-fix (claude-sonnet-4.6) | Use ResourceLoader.ExceptionHandler2 as discriminator in APV instead of Context.ExceptionHandler; return null in StaticResourceExtension |
✅ PASS | 2 files | Directly addresses code review |
| 3 | try-fix (gpt-5.3-codex) | Read current property value via IProvideValueTarget and return it on Hot Reload |
✅ PASS | 1 file (StaticResourceExtension.cs) |
Preserves existing value; more complex; adds GetCurrentPropertyValue helper |
| 4 | try-fix (claude-opus-4.7) | Minimal — return null after ehandler.Invoke in StaticResourceExtension.ProvideValue only; zero APV changes |
✅ PASS | 1 file (StaticResourceExtension.cs) |
Simplest possible fix; eliminates APV regression concern entirely |
| PR | PR #35020 | return null in StaticResourceExtension.ProvideValue when ExceptionHandler2 set + defense-in-depth APV catch using Context.ExceptionHandler as discriminator |
✅ PASSED (Gate) | 2 files | Original PR; APV discriminator concern flagged by code review |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| claude-sonnet-4.6 | 2 | Yes | Fix at Hot Reload orchestrator level — wrap InitializeComponent() in try/catch in HotReloadService; architecturally orthogonal but incompatible with current test suite (tests call inflator directly, not through orchestrator) → not runnable, declared N/A |
Exhausted: Yes — all 4 models queried, no additional runnable ideas beyond cross-pollination suggestion (untestable with current test suite).
Selected Fix: Candidate #2 (claude-sonnet-4.6) — Uses ResourceLoader.ExceptionHandler2 as the discriminator in ApplyPropertiesVisitor instead of Context.ExceptionHandler. This is superior to the PR's fix because it directly addresses the code review's Context.ExceptionHandler discriminator in APV is broader than necessary and was specifically flagged by the code review.
📋 Report — Final Recommendation
⚠️ Final Recommendation: REQUEST CHANGES
Phase Status
| Phase | Status | Notes |
|---|---|---|
| Pre-Flight | ✅ COMPLETE | Issue #35018, iOS Hot Reload StaticResource crash regression from PR #33859 |
| Code Review | NEEDS_DISCUSSION (medium) | 0 errors, 1 warning, 2 suggestions |
| Gate | ✅ PASSED | ios |
| Try-Fix | ✅ COMPLETE | 4 attempts, 4 passing |
| Report | ✅ COMPLETE |
Code Review Impact on Try-Fix
The code review's ApplyPropertiesVisitor using Context.ExceptionHandler as the discriminator directly shaped fix exploration. Attempt 2 (claude-sonnet-4.6) specifically addressed this by switching the APV discriminator to ResourceLoader.ExceptionHandler2 — the Hot Reload-specific flag — instead of the generic Context.ExceptionHandler. This eliminates the #23903 regression risk. Attempts 1, 3, and 4 chose to skip APV changes entirely, which is also valid. The code review finding produced a clearly superior alternative to the PR's approach.
Summary
The PR correctly fixes a Hot Reload crash on iOS where a missing {StaticResource} key caused an exception to propagate through UIKit Shell lifecycle callbacks, corrupting state. The primary fix (returning null from StaticResourceExtension.ProvideValue when ExceptionHandler2 is set) is correct, minimal, and well-tested. The secondary defense-in-depth catch in ApplyPropertiesVisitor works but uses a discriminator (Context.ExceptionHandler) that is broader than necessary and implicitly reverts the #23903 fix for a generic handler scenario. Try-Fix found a better-scoped alternative that uses ResourceLoader.ExceptionHandler2 in APV instead.
Root Cause
PR #33859 (commit 6874c80) changed StaticResourceExtension.ProvideValue to always throw even when ExceptionHandler2 is set, to fix #23903. On iOS, this exception now escapes through synchronous UIKit callbacks during Shell item setup (Shell.InitializeComponent → CreateTabRenderers → ViewDidLoad → LoadRenderers → GetOrCreateContent → page constructor → ProvideValue → throw), corrupting Shell state. Android/Windows are unaffected due to lazy content creation.
Fix Quality
The primary fix in StaticResourceExtension.cs is sound and all 4 try-fix models confirmed it passes. The ApplyPropertiesVisitor.cs defense-in-depth addition needs one targeted change: replace Context.ExceptionHandler != null with ResourceLoader.ExceptionHandler2 != null as the guard condition. This keeps the safety net strictly scoped to Hot Reload mode and avoids any implicit regression of the #23903 fix. The fix is otherwise well-documented and the tests are comprehensive (happy path + Hot Reload rename scenario, exception message verification, degraded-style assertion).
|
/review |
|
✅ Expert Code Review completed successfully! |
There was a problem hiding this comment.
Expert Code Review — PR #35020
Methodology: 3 independent reviewers with adversarial consensus (disputed findings verified by follow-up cross-examination).
Verdict: LGTM
Confidence: high
All 3 reviewers independently concluded this PR is correct, well-scoped, and safe to merge. The fix correctly restores graceful degradation for StaticResource resolution during Hot Reload while preserving strict behavior at normal launch. The defense-in-depth layer in ApplyPropertiesVisitor is a prudent addition.
Findings
🟢 MINOR — Inaccurate comment about value-type behavior (2/3 reviewers)
File: src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs, lines 43–45
The comment claims null is "silently ignored for value-type properties," but actually a secondary misleading diagnostic is reported via ExceptionHandler. See inline comment for details and suggested rewording.
🟢 MINOR — Consider adding value-type StaticResource test coverage (2/3 reviewers)
File: src/Controls/tests/Xaml.UnitTests/Issues/Maui35018.xaml
Both the new test and the existing HotReloadStaticResourceException test primarily exercise reference-type properties (Style). A value-type property (e.g., FontSize="{StaticResource MissingSize}") would exercise the null-to-value-type assignment path described above. Coverage for this path exists indirectly through the existing HotReloadStaticResourceException test (which references BackgroundColor and X), so this is low priority.
🟢 MINOR — Test assertion Assert.NotEqual could be more precise (2/3 reviewers after follow-up)
File: src/Controls/tests/Xaml.UnitTests/Issues/Maui35018.xaml.cs, line 96
Assert.NotEqual(32.0, reloadedPage.headlineLabel.FontSize) verifies the styled value is gone but doesn't assert what value it reverted to. One reviewer suggested Assert.Equal(DefaultValue, ...), but a follow-up reviewer noted Label.FontSizeProperty uses a defaultValueCreator, making DefaultValue unreliable as a comparison target. A fresh unstyled Label instance comparison would be more appropriate if this is addressed. Low priority since the primary purpose of this test is crash prevention, which is well-covered by the preceding assertions.
Discarded findings (1/3 only — single reviewer, not confirmed)
- Catch block in
ApplyPropertiesVisitoralso swallowsArgumentNullException/ missing-service-provider exceptions during Hot Reload — acceptable since these are reported to the handler and the defense-in-depth path is documented as rarely reached. - Removed
Assert.Containson exception message inHotReloadStaticResourceException— acceptable since the handler lambda already validates the message content.
CI Status & Test Coverage
- PR includes 2 new test methods (
InitialLoadWithResourceSucceeds,HotReloadAfterResourceRenameShouldNotCrash) covering Runtime and SourceGen inflators - Existing test (
HotReloadStaticResourceException) updated to reflect the intentional behavioral change - XamlC inflator correctly excluded (compile-time IL generation doesn't participate in Hot Reload)
- Tests gated on
#if DEBUGmatching the Hot Reload runtime context
Devil's Advocate Summary
- "Could null break downstream consumers?" — Verified:
TrySetValueguards against null for value-typeBindableProperty, andSetValue(property, null)clears reference-type properties cleanly. - "Could this affect non-Hot-Reload scenarios?" — No. The
return nullis gated onExceptionHandler2 != null, only set by the IDE during Hot Reload. Normal launch still throws. - "Is the behavioral change to the existing test a regression risk?" — No. The behavior table in the PR description clearly documents the intentional semantic change from #33859. The old "throw even with handler" behavior was the regression.
Generated by Expert Code Review for issue #35020 · ● 24.3M
| // Note: null clears reference-type properties (Style, ImageSource) and is | ||
| // silently ignored for value-type properties (FontSize, Thickness), which | ||
| // retain their previous value. |
There was a problem hiding this comment.
🟢 MINOR (2/3 reviewers)
This comment is slightly inaccurate. When ProvideValue returns null and the target is a non-nullable value-type BindableProperty (e.g., FontSize), the value is not "silently ignored" — the SetPropertyValue path in ApplyPropertiesVisitor will fail to convert null to the value type and report a secondary error to ExceptionHandler:
"Cannot assign property 'FontSize': Property does not exist, or is not assignable, or mismatching type between value and property"
This means developers may see two diagnostics in the IDE Error List for a single missing value-type resource: the correct "StaticResource not found" plus a misleading property-assignment error.
Suggestion: Consider rewording the comment to reflect actual behavior, e.g.:
// Note: null clears reference-type properties (Style, ImageSource). For
// non-nullable value-type properties (FontSize, Thickness), the assignment
// is skipped and an additional diagnostic may be reported.
…fy defense-in-depth comment - StaticResourceExtension: Correct comment about null behavior for value-type properties — assignment is skipped with an additional diagnostic, not silently ignored. - ApplyPropertiesVisitor: Simplify defense-in-depth comment to be more direct about the Hot Reload crash prevention purpose. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Multimodal Review — PR #35020Reviewed code, issue context (#35018), test design, prior reviewer threads, and verified end‑to‑end coupling between Verdict: LGTM with minor optional follow‑upsThe fix correctly restores graceful degradation for missing Correctness — verified ✅
Comments — accurate ✅The note about value‑type semantics on Tests — adequate ✅, with optional gapsThe new
Optional follow‑ups (non‑blocking):
Behavioral change to existing test — intentional and well‑scoped ✅The change to Risk surface beyond
|
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Fixes #35018 — The MAUI app quits with no errors after editing a ResourceDictionary XAML file on iOS Simulator during Hot Reload. ### Root Cause PR #33859 (commit 6874c80) changed `StaticResourceExtension.ProvideValue` to always throw `XamlParseException` for missing resources, even when `ExceptionHandler2` is set (Hot Reload / IDE context). This change was correct for app launch consistency (#23903), but on iOS it exposes a platform-specific weakness: During Hot Reload, the Shell rebuilds via `InitializeComponent()`, which on iOS synchronously triggers: ``` Shell.InitializeComponent() → adds ShellItems → iOS ShellItemRenderer.CreateTabRenderers() → UpdateTabBarHidden() → UIKit sets TabBarHidden → UIKit calls ViewDidLoad() synchronously → ShellSectionRootRenderer.LoadRenderers() → GetOrCreateContent() → MainPage constructor → StaticResourceExtension.ProvideValue() → XamlParseException ``` The exception propagates through UIKit lifecycle callbacks, corrupting Shell state and crashing the app. Android/Windows are unaffected because they create page content lazily. ### Fix Two changes that restore graceful degradation during Hot Reload: 1. **`StaticResourceExtension.ProvideValue`**: When `ExceptionHandler2` is set (Hot Reload), report the error to the handler and return `null` instead of throwing. Without a handler (normal launch), still throws. 2. **`ApplyPropertiesVisitor`**: When `ExceptionHandler` is set and `StaticResourceExtension` throws, skip the property assignment (set `value = null`, return) instead of re-throwing. The page loads with degraded styling. The error is still reported to the IDE via `ExceptionHandler2`, so the Error List shows the missing resource diagnostic. ### Comparison with #33859 | Scenario | Before #33859 | After #33859 | This PR | |----------|--------------|-------------|---------| | Missing resource, no handler (normal launch) | Throw | Throw | Throw ✅ | | Missing resource, handler set (Hot Reload) | Report + return null | Report + throw 💥 | Report + return null ✅ | ### Test Added `Maui35018.xaml` + `Maui35018.xaml.cs` — reproduces the Hot Reload resource rename scenario: - `InitialLoadWithResourceSucceeds` — page loads when "Headline" exists - `HotReloadAfterResourceRenameShouldNotCrash` — after removing "Headline" (simulating rename), page loads with handler invoked, no crash Updated `HotReloadStaticResourceException.xaml.cs` to match new behavior (page loads instead of throwing when handler is set). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ability (#35133) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! > **Depends on #35136** (pipeline category detection — should merge first) ## What this does Two things: ### 1. UI test category detection in PR review During the PR review workflow, Step 0.5 detects which UI test categories the PR impacts and writes the result to the AI summary comment. This gives reviewers visibility into which UI tests are relevant. **Detection** reuses the 3-tier script from #35136 (test attributes → source paths → AI reasoning). **AI summary** shows a new 🧪 UI Tests section with detected categories before the gate section. ### 2. Gate reliability fixes Multiple fixes to make the gate (`verify-tests-fail.ps1`) more deterministic: | Fix | Problem it solves | |-----|-------------------| | **Absolute path resolution** | Gate scripts not found on Linux CI agents (`Resolve-Path`, `GetFullPath`) | | **File existence check** | Instant cryptic failure when verify script is missing — now logs clear error | | **3x retry on ENV ERROR** | Emulator timeouts, ADB failures, app crashes — transient issues that pass on retry | | **Strip bad report blocks** | Old verify script produces `Passed: False` with empty counts — stripped instead of shown | | **Gate log in fallback** | When report is missing, shows last 20 lines of gate output instead of just `❌ FAILED / Platform: IOS` | ## Files | File | Changes | |------|---------| | `.github/scripts/Review-PR.ps1` | Step 0.5 category detection + all 5 gate fixes | | `.github/scripts/post-ai-summary-comment.ps1` | Add `uitests` phase to render detected categories | | `.github/pr-review/pr-preflight.md` | Step 7: AI identifies impacted UI test categories | ## Validation — PR reviewer builds (Apr 26) 10 builds against real PRs — all succeeded ✅. Category detection shown in AI summary comment. | PR | Categories Detected | Build | AI Summary | |----|-------------------|-------|------------| | #35037 (WebView theme) | `ViewBaseTests,WebView` | [13940071](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940071) | [comment](#35037 (comment)) | | #35031 (Shell memory leak) | `Shell` | [13940072](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940072) | [comment](#35031 (comment)) | | #35020 (XAML Hot Reload) | _(none — XAML only)_ | [13940073](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940073) | ✅ Shows "No UI test categories" | | #35008 (Shell SearchHandler) | `Shell` | [13940074](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940074) | ✅ | | #34997 (RadioButton gradient) | `RadioButton,ViewBaseTests` | [13940075](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940075) | ✅ | | #34980 (DatePicker rotation) | `ViewBaseTests` | [13940076](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940076) | ✅ | | #34974 (Picker CharacterSpacing) | `ViewBaseTests` | [13940077](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940077) | ✅ | | #34923 (SwipeView threshold) | `SwipeView,ViewBaseTests` | [13940078](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940078) | ✅ | | #34907 (CollectionView ScrollTo) | `CollectionView` | [13940079](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940079) | ✅ | | #34845 (RefreshView binding) | `RefreshView,ViewBaseTests` | [13940080](https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=13940080) | ✅ | --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Fixes #35018 — The MAUI app quits with no errors after editing a ResourceDictionary XAML file on iOS Simulator during Hot Reload. ### Root Cause PR #33859 (commit 6874c80) changed `StaticResourceExtension.ProvideValue` to always throw `XamlParseException` for missing resources, even when `ExceptionHandler2` is set (Hot Reload / IDE context). This change was correct for app launch consistency (#23903), but on iOS it exposes a platform-specific weakness: During Hot Reload, the Shell rebuilds via `InitializeComponent()`, which on iOS synchronously triggers: ``` Shell.InitializeComponent() → adds ShellItems → iOS ShellItemRenderer.CreateTabRenderers() → UpdateTabBarHidden() → UIKit sets TabBarHidden → UIKit calls ViewDidLoad() synchronously → ShellSectionRootRenderer.LoadRenderers() → GetOrCreateContent() → MainPage constructor → StaticResourceExtension.ProvideValue() → XamlParseException ``` The exception propagates through UIKit lifecycle callbacks, corrupting Shell state and crashing the app. Android/Windows are unaffected because they create page content lazily. ### Fix Two changes that restore graceful degradation during Hot Reload: 1. **`StaticResourceExtension.ProvideValue`**: When `ExceptionHandler2` is set (Hot Reload), report the error to the handler and return `null` instead of throwing. Without a handler (normal launch), still throws. 2. **`ApplyPropertiesVisitor`**: When `ExceptionHandler` is set and `StaticResourceExtension` throws, skip the property assignment (set `value = null`, return) instead of re-throwing. The page loads with degraded styling. The error is still reported to the IDE via `ExceptionHandler2`, so the Error List shows the missing resource diagnostic. ### Comparison with #33859 | Scenario | Before #33859 | After #33859 | This PR | |----------|--------------|-------------|---------| | Missing resource, no handler (normal launch) | Throw | Throw | Throw ✅ | | Missing resource, handler set (Hot Reload) | Report + return null | Report + throw 💥 | Report + return null ✅ | ### Test Added `Maui35018.xaml` + `Maui35018.xaml.cs` — reproduces the Hot Reload resource rename scenario: - `InitialLoadWithResourceSucceeds` — page loads when "Headline" exists - `HotReloadAfterResourceRenameShouldNotCrash` — after removing "Headline" (simulating rename), page loads with handler invoked, no crash Updated `HotReloadStaticResourceException.xaml.cs` to match new behavior (page loads instead of throwing when handler is set). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/backport to release/10.0.1xx-sr7 |
|
Started backporting to |
…OS (#35425) Backport of #35020 to release/10.0.1xx-sr7 /cc @kubaflo @StephaneDelcroix --------- Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com>
<!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description Fixes #35018 — The MAUI app quits with no errors after editing a ResourceDictionary XAML file on iOS Simulator during Hot Reload. ### Root Cause PR #33859 (commit 6874c80) changed `StaticResourceExtension.ProvideValue` to always throw `XamlParseException` for missing resources, even when `ExceptionHandler2` is set (Hot Reload / IDE context). This change was correct for app launch consistency (#23903), but on iOS it exposes a platform-specific weakness: During Hot Reload, the Shell rebuilds via `InitializeComponent()`, which on iOS synchronously triggers: ``` Shell.InitializeComponent() → adds ShellItems → iOS ShellItemRenderer.CreateTabRenderers() → UpdateTabBarHidden() → UIKit sets TabBarHidden → UIKit calls ViewDidLoad() synchronously → ShellSectionRootRenderer.LoadRenderers() → GetOrCreateContent() → MainPage constructor → StaticResourceExtension.ProvideValue() → XamlParseException ``` The exception propagates through UIKit lifecycle callbacks, corrupting Shell state and crashing the app. Android/Windows are unaffected because they create page content lazily. ### Fix Two changes that restore graceful degradation during Hot Reload: 1. **`StaticResourceExtension.ProvideValue`**: When `ExceptionHandler2` is set (Hot Reload), report the error to the handler and return `null` instead of throwing. Without a handler (normal launch), still throws. 2. **`ApplyPropertiesVisitor`**: When `ExceptionHandler` is set and `StaticResourceExtension` throws, skip the property assignment (set `value = null`, return) instead of re-throwing. The page loads with degraded styling. The error is still reported to the IDE via `ExceptionHandler2`, so the Error List shows the missing resource diagnostic. ### Comparison with #33859 | Scenario | Before #33859 | After #33859 | This PR | |----------|--------------|-------------|---------| | Missing resource, no handler (normal launch) | Throw | Throw | Throw ✅ | | Missing resource, handler set (Hot Reload) | Report + return null | Report + throw 💥 | Report + return null ✅ | ### Test Added `Maui35018.xaml` + `Maui35018.xaml.cs` — reproduces the Hot Reload resource rename scenario: - `InitialLoadWithResourceSucceeds` — page loads when "Headline" exists - `HotReloadAfterResourceRenameShouldNotCrash` — after removing "Headline" (simulating rename), page loads with handler invoked, no crash Updated `HotReloadStaticResourceException.xaml.cs` to match new behavior (page loads instead of throwing when handler is set). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…5362) This pull request includes several test improvements and bug fixes across the test suite, focusing on memory leak detection, platform-specific test handling, and test reliability. The changes enhance memory leak checks for Shell TitleView, improve platform annotations, and address issues with test flakiness and correctness. **Memory leak detection and test improvements:** * Enhanced the memory leak test for Shell TitleView (`Issue34975`) to use a more robust approach: now tracks page references with a `WeakReference` array and performs an additional navigation round to ensure proper garbage collection, especially on macOS. The status label now reports how many instances remain alive, improving test diagnostics. [[1]](diffhunk://#diff-43d7a42c328825366824a5852b493c4701b584d4bdcc89251732a793426f3a1fR32-R62) [[2]](diffhunk://#diff-cd685f092bc837dc334a2611f1109b29b358a4676a65e3aee577eaef177f8197L23-R26) * Updated the `[Issue]` attribute for `Issue34975` to include `PlatformAffected.macOS`, ensuring the test runs on both iOS and macOS platforms. **Platform-specific test handling and reliability:** * Adjusted test conditions in `CollectionView_ScrollingFeatureTests.cs` to include Windows in platform-specific skip logic and added comments referencing related issues, improving test clarity and reliability. [[1]](diffhunk://#diff-d0158d1415828d2b2a784462d5b03cadbc262b1cd822351d96b35b146976da66L1226-R1226) [[2]](diffhunk://#diff-d0158d1415828d2b2a784462d5b03cadbc262b1cd822351d96b35b146976da66R1580) [[3]](diffhunk://#diff-d0158d1415828d2b2a784462d5b03cadbc262b1cd822351d96b35b146976da66R1793) * Updated the swipe item visibility change test (`Issue7580`) to account for platform differences: on Windows, the test waits for a UI element instead of asserting label text, increasing test robustness. **Code cleanup and test maintenance:** * In PR #33859, the issue was fixed by always throwing an exception when an undefined control template was applied to a page. However, since this behavior broke Hot Reload scenarios, the fix was later reverted in SR6 through PR #35130. * After that, PR #35020 restored the previous behavior by returning normally instead of throwing an exception. * The test "Issue #23903: Missing ControlTemplate with exception handler should throw" was originally added in PR #33859 to validate that an exception was thrown when an undefined control template was applied. Since the fix was later reverted, the test started failing. Therefore, the test was removed in this PR. **Images:** * Resaved the valid iOS, Mac, and Windows images. **Fixes:** #35234 --------- Co-authored-by: KarthikRajaKalaimani <92777139+KarthikRajaKalaimani@users.noreply.github.com> Co-authored-by: Shalini-Ashokan <102292178+Shalini-Ashokan@users.noreply.github.com> Co-authored-by: LogishaSelvarajSF4525 <logisha.selvaraj@syncfusion.com> Co-authored-by: HarishwaranVijayakumar <harishwaran.vijayakumar@syncfusion.com>
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Description
Fixes #35018 — The MAUI app quits with no errors after editing a ResourceDictionary XAML file on iOS Simulator during Hot Reload.
Root Cause
PR #33859 (commit 6874c80) changed
StaticResourceExtension.ProvideValueto always throwXamlParseExceptionfor missing resources, even whenExceptionHandler2is set (Hot Reload / IDE context). This change was correct for app launch consistency (#23903), but on iOS it exposes a platform-specific weakness:During Hot Reload, the Shell rebuilds via
InitializeComponent(), which on iOS synchronously triggers:The exception propagates through UIKit lifecycle callbacks, corrupting Shell state and crashing the app. Android/Windows are unaffected because they create page content lazily.
Fix
Two changes that restore graceful degradation during Hot Reload:
StaticResourceExtension.ProvideValue: WhenExceptionHandler2is set (Hot Reload), report the error to the handler and returnnullinstead of throwing. Without a handler (normal launch), still throws.ApplyPropertiesVisitor: WhenExceptionHandleris set andStaticResourceExtensionthrows, skip the property assignment (setvalue = null, return) instead of re-throwing. The page loads with degraded styling.The error is still reported to the IDE via
ExceptionHandler2, so the Error List shows the missing resource diagnostic.Comparison with #33859
Test
Added
Maui35018.xaml+Maui35018.xaml.cs— reproduces the Hot Reload resource rename scenario:InitialLoadWithResourceSucceeds— page loads when "Headline" existsHotReloadAfterResourceRenameShouldNotCrash— after removing "Headline" (simulating rename), page loads with handler invoked, no crashUpdated
HotReloadStaticResourceException.xaml.csto match new behavior (page loads instead of throwing when handler is set).