dotnet/wpf · error · ArgumentException

SR.Format(SR.MarkupExtensionNoContext, GetType().Name…

Error message

SR.Format(SR.MarkupExtensionNoContext, GetType().Name, "IXamlTypeResolver")

What it means

StaticExtension.ProvideValue requires the service provider passed to it to supply the IXamlTypeResolver service, which is what converts the type name in the Member string into a Type. If serviceProvider.GetService(typeof(IXamlTypeResolver)) returns null (the context is not a XAML parser context), the extension cannot resolve names and throws ArgumentException with MarkupExtensionNoContext.

Solutions

  1. Obtain the service provider from a real XAML parse (put the extension in XAML instead of calling ProvideValue manually).
  2. Register IXamlTypeResolver on the service provider you pass: sp.AddService(typeof(IXamlTypeResolver), resolver) with a working implementation (e.g. XamlTypeResolver backed by the ParserContext's XmlnsDictionary).
  3. In tests, implement a fake IXamlTypeResolver whose Resolve returns the expected Type and register it in the test service provider.
  4. If you only know the Type already, skip resolution entirely and use StaticExtension(Member, type) or access the member directly via reflection.

Example fix

// before
var sp = new ServiceProvider();
var value = new StaticExtension("sys:String.Empty").ProvideValue(sp); // throws: no IXamlTypeResolver
// after
sp.AddService(typeof(IXamlTypeResolver), new TestXamlTypeResolver());
var value = new StaticExtension("sys:String.Empty").ProvideValue(sp);
Defensive patterns

Strategy: try-catch

Validate before calling

var resolver = serviceProvider?.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
bool canProvide = resolver != null;

Type guard

static bool HasTypeResolver(IServiceProvider sp) => sp?.GetService(typeof(IXamlTypeResolver)) is IXamlTypeResolver;

Try / catch

try { return ext.ProvideValue(sp); }
catch (ArgumentException ex) when (ex.Message.Contains("IXamlTypeResolver")) { return fallbackValue; }

Prevention

When it happens

Trigger: Calling StaticExtension.ProvideValue with a plain ServiceProvider or a mock that does not register IXamlTypeResolver; invoking the extension outside a real XAML parse (e.g. manually in unit tests or from design-time code without a parser context).

Common situations: Unit-testing a markup extension with a bare ServiceProvider; calling ProvideValue on a markup extension after deserializing it from BAML outside a parser; custom designer/extensibility code that passes an incomplete service provider.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Markup/StaticExtension.cs:83

                    throw new ArgumentException(SR.Format(SR.MarkupExtensionBadStatic, Member));
                }

                // Pull out the type substring (this will include any XML prefix, e.g. "av:Button")

                string typeString = Member.Substring(0, dotIndex);
                if (typeString == string.Empty)
                {
                    throw new ArgumentException(SR.Format(SR.MarkupExtensionBadStatic, Member));
                }

                // Get the IXamlTypeResolver from the service provider

                ArgumentNullException.ThrowIfNull(serviceProvider);

                IXamlTypeResolver xamlTypeResolver = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
                if (xamlTypeResolver == null)
                {
                    throw new ArgumentException(SR.Format(SR.MarkupExtensionNoContext, GetType().Name, "IXamlTypeResolver"));
                }

                // Use the type resolver to get a Type instance

                MemberType = xamlTypeResolver.Resolve(typeString);

                // Get the member name substring

                Member = Member.Substring(dotIndex + 1, Member.Length - dotIndex - 1);
            }

            value = CommandConverter.GetKnownControlCommand(MemberType, Member);
            if (value != null)
            {
                return value;
            }

            return base.ProvideValue(serviceProvider);

View on GitHub (pinned to 81131a70a4)