Skip to content

[iOS] Fix StaticResource Hot Reload crash on iOS#35020

Merged
kubaflo merged 3 commits into
inflight/currentfrom
fix/35018-staticresource-hotreload-crash
Apr 29, 2026
Merged

[iOS] Fix StaticResource Hot Reload crash on iOS#35020
kubaflo merged 3 commits into
inflight/currentfrom
fix/35018-staticresource-hotreload-crash

Conversation

@StephaneDelcroix
Copy link
Copy Markdown
Contributor

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.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).

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>
Copilot AI review requested due to automatic review settings April 17, 2026 16:47
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 17, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35020

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35020"

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.ProvideValue to return null (after reporting) instead of throwing when ResourceLoader.ExceptionHandler2 is set.
  • Update ApplyPropertiesVisitor to avoid rethrowing StaticResourceExtension failures 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).

Comment on lines +288 to +291
// 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).
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
// 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);

Copilot uses AI. Check for mistakes.
@noiseonwires
Copy link
Copy Markdown
Member

noiseonwires commented Apr 18, 2026

@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)?

@PureWeen
Copy link
Copy Markdown
Member

Multi-Model Code Review — PR #35020

PR: [iOS] Fix StaticResource Hot Reload crash on iOS
Author: @StephaneDelcroix | Fixes: #35018
Review method: 3 independent reviewers, adversarial consensus


CI Status

Check Status
Build (Windows/macOS, Debug/Release) ✅ All pass
Pack (Windows/macOS) ✅ All pass
Integration Tests (all categories) ✅ All pass
Helix Unit Tests (Release) ✅ Pass
Helix Unit Tests (Debug) Fail

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 HotReloadStaticResourceException test expectations.


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 StaticResourceExtension. However, this is correct: other markup extensions already had "swallow on handler" behavior in ApplyPropertiesVisitor (lines 296–300). StaticResourceExtension was the one explicitly changed in PR #33859 to always rethrow, and this PR correctly reverts that regression for the Hot Reload case only.


Findings

🟡 MODERATE — ApplyPropertiesVisitor catch block is dead code that drops handler notification (3/3 reviewers)

File: src/Controls/src/Xaml/ApplyPropertiesVisitor.cs, new lines 284–291

All 3 reviewers independently identified that fix #2 (the ApplyPropertiesVisitor catch block) is unreachable when fix #1 is applied. When ExceptionHandler2 is set, StaticResourceExtension.ProvideValue now returns null without throwing — so the catch block is never entered.

This is because Context.ExceptionHandler is derived from ExceptionHandler2 in XamlLoader.cs:

var doNotThrow = ResourceLoader.ExceptionHandler2 != null;
ExceptionHandler = doNotThrow ? ehandler : null

They are always set together. When ExceptionHandler2 prevents the throw, ExceptionHandler would also be non-null — but the catch block is never reached.

More critically, the new code drops the Context.ExceptionHandler invocation. The old code called Context.ExceptionHandler?.Invoke(e) before rethrowing. The new code sets value = null and returns without invoking the handler. If this path ever becomes reachable (e.g., future refactoring removes fix #1, or a caller sets ExceptionHandler independently), errors will be silently swallowed with no notification.

Suggested fix: Either (a) remove fix #2 entirely since fix #1 is sufficient, or (b) if keeping as defense-in-depth, invoke the handler:

if (Context.ExceptionHandler != null)
{
    Context.ExceptionHandler.Invoke(e);  // report before skipping
    value = null;
    return;
}

🟡 MODERATE — null return has different semantics for different property types (3/3 reviewers)

File: src/Controls/src/Xaml/MarkupExtensions/StaticResourceExtension.cs, line 39 (return null)

Returning null from ProvideValue causes the property to be assigned null, not skipped. The behavior differs by property type:

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

⚠️ Request changes — Two items to address:

  1. Investigate the Helix Unit Tests Debug failure — determine if it's related to the behavioral change in HotReloadStaticResourceException test expectations or a pre-existing flaky test. If PR-specific, fix it.

  2. Fix the ApplyPropertiesVisitor catch block — either remove it (fix [Draft] Readme WIP #1 is sufficient) or add Context.ExceptionHandler.Invoke(e) before the value = 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>
@MauiBot
Copy link
Copy Markdown
Collaborator

MauiBot commented Apr 26, 2026

🤖 AI Summary

👋 @StephaneDelcroix — new AI review results are available. Please review the latest session below.

📊 Review Session004d2dd · Address review feedback: handler invocation, test assertions, comments · 2026-04-26 11:59 UTC
🚦 Gate — Test Before & After Fix

Gate Result: ✅ PASSED

Platform: IOS · Base: main · Merge base: 2e137135

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.cs
  • src/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.ProvideValue was changed by PR [Android, iOS] Throw exceptions consistently for invalid StaticResource references to prevent relaunch crashes #33859 to always throw even when ExceptionHandler2 (Hot Reload IDE handler) is set. On iOS, this exception propagates synchronously through UIKit Shell lifecycle callbacks during Shell.InitializeComponent(), corrupting Shell state and crashing the app.
  • Fix 1 (StaticResourceExtension.cs): When ExceptionHandler2 is set, report the error and return null instead of throwing.
  • Fix 2 (ApplyPropertiesVisitor.cs): Defense-in-depth catch block — if StaticResourceExtension throws 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.ExceptionHandler invocation; this has since been addressed (handler IS invoked before value = null; return;).
  • Existing test HotReloadStaticResourceException.xaml.cs updated: was asserting Assert.Throws<XamlParseException>, now asserts page loads without throwing.
  • New test Maui35018 adds 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:

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.ExceptionHandler is set · ExceptionHandler2 is 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):

null clears 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 ⚠️ — swallow only fires in Hot Reload, never for generic handlers
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 ⚠️ warning: the APV exception swallow is now strictly scoped to Hot Reload mode, eliminating the #23903 regression risk. It passes all 6 tests. The PR's fix is functionally correct but the 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 ⚠️ warning about 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).


@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-win AI found a better alternative fix than the PR s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Apr 26, 2026
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Apr 28, 2026

/review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 28, 2026

Expert Code Review completed successfully!

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ApplyPropertiesVisitor also swallows ArgumentNullException / 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.Contains on exception message in HotReloadStaticResourceException — 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 DEBUG matching the Hot Reload runtime context

Devil's Advocate Summary

  • "Could null break downstream consumers?" — Verified: TrySetValue guards against null for value-type BindableProperty, and SetValue(property, null) clears reference-type properties cleanly.
  • "Could this affect non-Hot-Reload scenarios?" — No. The return null is gated on ExceptionHandler2 != 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

Comment on lines +43 to +45
// Note: null clears reference-type properties (Style, ImageSource) and is
// silently ignored for value-type properties (FontSize, Thickness), which
// retain their previous value.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 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>
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Apr 29, 2026

Multimodal Review — PR #35020

Reviewed code, issue context (#35018), test design, prior reviewer threads, and verified end‑to‑end coupling between ResourceLoader.ExceptionHandler2 and HydrationContext.ExceptionHandler.

Verdict: LGTM with minor optional follow‑ups

The fix correctly restores graceful degradation for missing {StaticResource} during Hot Reload while preserving strict throw‑on‑launch semantics. Comments now accurately describe behavior, the handler is invoked before the property is skipped in both code paths, and the regression tracking back to #33859 is well documented in the PR body.


Correctness — verified ✅

  • StaticResourceExtension.ProvideValue only short‑circuits to return null when ResourceLoader.ExceptionHandler2 != null (Hot Reload only). Normal launch still throws — matches the table in the PR description.
  • The defense‑in‑depth catch in ApplyPropertiesVisitor is gated on Context.ExceptionHandler != null, which XamlLoader always sets in lock‑step with ResourceLoader.ExceptionHandler2 (XamlLoader.cs:101, 121, 147, 191). So the two gates are guaranteed consistent — no risk of one path swallowing while the other rethrows.
  • Crucially, the new catch block invokes Context.ExceptionHandler(e) before skipping the property, so an earlier review concern about silently dropping non‑“missing‑resource” StaticResourceExtension exceptions (null Key, missing services, etc.) is addressed. Not dead code — it now gracefully handles every StaticResourceExtension‑sourced exception during Hot Reload.

Comments — accurate ✅

The note about value‑type semantics on StaticResourceExtension.cs is correct: a null return for non‑nullable BPs (e.g., FontSize, Thickness) is filtered by TrySetValue (ApplyPropertiesVisitor.cs:625-628) and falls through to the “Cannot assign property…” diagnostic at line 439, which is reported via Context.ExceptionHandler. The IDE may therefore see two diagnostics for one missing value‑type resource. That trade‑off is acceptable given the fix prevents an app crash, and is now documented inline.

Tests — adequate ✅, with optional gaps

The new Maui35018 tests + the updated HotReloadStaticResourceException test correctly:

  • Cover both Runtime and SourceGen inflators (XamlC exclusion is justified by the inline comment).
  • Validate handler invocation, no‑throw behavior, and degraded styling on the reference‑type (Style) path.

Optional follow‑ups (non‑blocking):

  1. Value‑type coverage gap. The PR explicitly documents a secondary‑diagnostic behavior for non‑nullable value‑type properties, but no test exercises it. A small addition like:
    <Label FontSize="{StaticResource MissingSize}" />
    inside an #if DEBUG test would lock down both that the page still loads and that the secondary “Cannot assign property” diagnostic surfaces. Currently a regression in that path could land silently.
  2. Test name overstates coverage. HotReloadAfterResourceRenameShouldNotCrash cannot actually exercise the iOS UIKit reentrancy path — it’s an xUnit test, not a device test. It verifies the XAML‑level behavior change that prevents the crash. A name like HotReloadAfterResourceRename_ReportsAndDegrades (or similar) more honestly describes what the test does. The XAML‑level coverage here is the right level of test for this fix; just the naming.
  3. Assert.NotEqual(32.0, reloadedPage.headlineLabel.FontSize) proves the styled value is gone, but a positive assertion against new Label().FontSize would pin down the expected default and catch a future regression where a different (non‑32) value gets assigned. Minor.

Behavioral change to existing test — intentional and well‑scoped ✅

The change to HotReloadStaticResourceException (no longer asserts a throw) is the explicit semantic reversal of #33859 for the Hot Reload case only. The PR description’s comparison table makes this clear. The lambda inside the handler still validates the diagnostic message content, so the contract is preserved.

Risk surface beyond StaticResource

Worth noting (in response to @noiseonwires’s question): this PR is intentionally narrow — only StaticResourceExtension was changed by #33859 to always throw. Other markup extensions (DynamicResource, Binding, type converters) already participate in the standard if (Context.ExceptionHandler != null) { handler(e); } else { throw; } flow at lines 293–296, so they don’t need the same treatment. The fix correctly does not expand its scope.

CI

CI was pending at review time. The prior expert review noted a Helix Unit Tests (Debug) failure on an earlier commit; please confirm the latest commit (805960e) is green before merge, and especially that MissingResourceExceptionAreHandled and the new Maui35018 theories pass on Debug for both Runtime and SourceGen.


Posted as a code‑review comment, not an approval — approval/changes‑requested decisions are reserved for human reviewers.

@kubaflo kubaflo changed the base branch from main to inflight/current April 29, 2026 12:59
@kubaflo kubaflo merged commit 12c73fc into inflight/current Apr 29, 2026
31 checks passed
@kubaflo kubaflo deleted the fix/35018-staticresource-hotreload-crash branch April 29, 2026 12:59
@github-actions github-actions Bot added this to the .NET 10 SR7 milestone Apr 29, 2026
PureWeen pushed a commit that referenced this pull request Apr 29, 2026
<!-- 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>
PureWeen pushed a commit that referenced this pull request Apr 30, 2026
…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>
github-actions Bot pushed a commit that referenced this pull request May 6, 2026
<!-- 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>
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented May 13, 2026

/backport to release/10.0.1xx-sr7

@github-actions
Copy link
Copy Markdown
Contributor

Started backporting to release/10.0.1xx-sr7 (link to workflow run)

PureWeen pushed a commit that referenced this pull request May 15, 2026
…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>
@kubaflo kubaflo added s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-fix-implemented PR author implemented the agent suggested fix s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation labels May 20, 2026
github-actions Bot pushed a commit that referenced this pull request May 25, 2026
<!-- 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>
kubaflo pushed a commit that referenced this pull request May 26, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-implemented PR author implemented the agent suggested fix s/agent-fix-win AI found a better alternative fix than the PR s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The maui app quit and no errors in error list after editing ResourceDictionary XAML file on iOS Simulator with MAUI SR6 10.0.60

6 participants