dotnet/wpf · error · InvalidOperationException

IAmbientProvider

Error message

IAmbientProvider

What it means

FindTheResourceDictionary next requests IAmbientProvider from the IServiceProvider; if missing it throws InvalidOperationException (MarkupExtensionNoContext naming "IAmbientProvider"). StaticResource resolution needs ambient (ancestor) value lookup, which only the XAML loader provides.

Solutions

  1. Use the extension only within real XAML markup where the loader supplies IAmbientProvider.
  2. In code, replace with element.FindResource/TryFindResource or Resources["key"] lookups.
  3. Complete the IServiceProvider so it also serves IAmbientProvider (usually by going through the standard XAML reader/writer pipeline).

Example fix

// before
var sp = new ServiceProvider(); sp.Add(typeof(IXamlSchemaContextProvider), ctx);
var v = ext.ProvideValue(sp); // missing IAmbientProvider
// after
var v = element.FindResource("MyKey");
Defensive patterns

Strategy: fallback

Validate before calling

bool hasAmbient = serviceProvider?.GetService(typeof(IAmbientProvider)) != null;
if (!hasAmbient) { /* resolve via element.FindResource instead */ }

Type guard

static bool SupportsAmbientLookup(IServiceProvider sp) => sp?.GetService(typeof(IAmbientProvider)) is IAmbientProvider;

Try / catch

try { value = ext.ProvideValue(sp); }
catch (InvalidOperationException ex) when (ex.Message.Contains("IAmbientProvider")) { value = element.FindResource(key); }

Prevention

When it happens

Trigger: Invoking StaticResourceExtension.ProvideValue with a service provider that supplies IXamlSchemaContextProvider but not IAmbientProvider, or running the extension outside a XAML parse with an incomplete service container.

Common situations: Hand-rolled service providers in tests or design-time tools that stub one service but not the other; custom XAML pipelines built with XamlObjectWriter settings that disable ambient property lookup.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/744316fa3960d739. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/StaticResourceExtension.cs:204

                             : prefetchedValue.GetValue(BaseValueSourceInternal.Unknown);
                }

            }
            return value;
        }

        private ResourceDictionary FindTheResourceDictionary(IServiceProvider serviceProvider, bool isDeferredContentSearch)
        {
            var schemaContextProvider = serviceProvider.GetService(typeof(IXamlSchemaContextProvider)) as IXamlSchemaContextProvider;
            if (schemaContextProvider == null)
            {
                throw new InvalidOperationException(SR.Format(SR.MarkupExtensionNoContext, GetType().Name, "IXamlSchemaContextProvider"));
            }

            var ambientProvider = serviceProvider.GetService(typeof(IAmbientProvider)) as IAmbientProvider;
            if (ambientProvider == null)
            {
                throw new InvalidOperationException(SR.Format(SR.MarkupExtensionNoContext, GetType().Name, "IAmbientProvider"));
            }

            XamlSchemaContext schemaContext = schemaContextProvider.SchemaContext;

            // This seems like a lot of work to do on every Provide Value
            // but that types and properties are cached in the schema.
            //
            XamlType feXType = schemaContext.GetXamlType(typeof(FrameworkElement));
            XamlType styleXType = schemaContext.GetXamlType(typeof(Style));
            XamlType templateXType = schemaContext.GetXamlType(typeof(FrameworkTemplate));
            XamlType appXType = schemaContext.GetXamlType(typeof(Application));
            XamlType fceXType = schemaContext.GetXamlType(typeof(FrameworkContentElement));

            XamlMember fceResourcesProperty = fceXType.GetMember("Resources");
            XamlMember feResourcesProperty = feXType.GetMember("Resources");
            XamlMember styleResourcesProperty = styleXType.GetMember("Resources");
            XamlMember styleBasedOnProperty = styleXType.GetMember("BasedOn");
            XamlMember templateResourcesProperty = templateXType.GetMember("Resources");

View on GitHub (pinned to 81131a70a4)