dotnet/wpf · error · ArgumentException

SR.SimpleFixupsMustHaveOneName

Error message

SR.SimpleFixupsMustHaveOneName

What it means

GetFixupToken builds a fixup token for deferred name resolution. When the token can assign directly (CanAssignDirectly), exactly one name must be supplied; otherwise the token throws ArgumentException(SimpleFixupsMustHaveOneName, nameof(names)).

Solutions

  1. Pass canAssignDirectly: false when more than one name is pending.
  2. Only use the direct-assignment path when exactly one name remains unresolved.
  3. Check names.Count() == 1 before requesting the token and fall back to the non-direct mode.
  4. Catch ArgumentException and retry with canAssignDirectly set to false.

Example fix

// before
var token = nameResolver.GetFixupToken(pendingNames, canAssignDirectly: true); // throws for 0 or 2+ names
// after
var token = nameResolver.GetFixupToken(pendingNames, canAssignDirectly: pendingNames.Count() == 1);
Defensive patterns

Strategy: validation

Validate before calling

int count = names?.Count() ?? 0;
if (canAssignDirectly && count != 1) throw new ArgumentException($"Direct assignment requires exactly one name, got {count}");

Type guard

bool EligibleForDirectAssign(IEnumerable<string> names) => names != null && names.Count() == 1;

Try / catch

try { return resolver.GetFixupToken(names, canAssignDirectly: true); }
catch (ArgumentException) { return resolver.GetFixupToken(names, canAssignDirectly: false); }

Prevention

When it happens

Trigger: Calling IServiceProvider/IXamlNameResolver.GetFixupToken(names, canAssignDirectly: true) with a names collection whose Count != 1 (empty or multiple names).

Common situations: Custom IXamlNameResolver implementations or markup extensions forwarding all pending names with canAssignDirectly hardcoded true; forward-reference handling code that batches multiple unresolved names.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/Context/ServiceProviderContext.cs:297

            return ((IXamlNameResolver)this).GetFixupToken(names, false);
        }

        object IXamlNameResolver.GetFixupToken(IEnumerable<string> names, bool canAssignDirectly)
        {
            if (_xamlContext.NameResolutionComplete)
            {
                return null;
            }

            var token = new NameFixupToken
            {
                CanAssignDirectly = canAssignDirectly
            };

            token.NeededNames.AddRange(names);
            if (token.CanAssignDirectly && token.NeededNames.Count != 1)
            {
                throw new ArgumentException(SR.SimpleFixupsMustHaveOneName, nameof(names));
            }

            // TypeConverter case (aka "Initialization")
            if (_xamlContext.CurrentType is null)
            {
                // If this is OBJECT Initialization
                if (_xamlContext.ParentProperty == XamlLanguage.Initialization)
                {
                    token.FixupType = FixupType.ObjectInitializationValue;

                    // If this is object initialization syntax:
                    //  SO Button>
                    //    SM Background
                    //       SO RefObject
                    //         SM _Initialization
                    //           V "_name"
                    // This TC will return the RefObject and
                    // The fixup is to Button.Background  (the grand parent)

View on GitHub (pinned to 81131a70a4)