dotnet/wpf · error · InvalidOperationException

SR.Format(SR.XamlMarkupExtensionWriterDuplicateMember…

Error message

SR.Format(SR.XamlMarkupExtensionWriterDuplicateMember, property.Name)

What it means

XamlMarkupExtensionWriter.CheckMemberForUniqueness tracks members written for the current object node in a XamlPropertySet; writing the same member twice throws InvalidOperationException with SR.XamlMarkupExtensionWriterDuplicateMember. Within a markup extension each property may be specified only once.

Solutions

  1. Remove the duplicate property assignment in the markup extension usage so each property appears once.
  2. Deduplicate members in your node-stream producer before writing (check objectNode.Members.Contains).
  3. Catch InvalidOperationException in writer pipelines consuming untrusted XAML and surface a good parse error.
  4. Fix the generator/serializer emitting the duplicated member.

Example fix

// before
// {MyExtension Value=1, Value=2}
// after
// {MyExtension Value=2}
Defensive patterns

Strategy: validation

Validate before calling

var seen = new HashSet<XamlProperty>();
// per object node, before each WriteStartMember(property):
if (!seen.Add(property)) throw new InvalidOperationException($"Duplicate member {property.Name} in markup extension.");

Try / catch

try { writer.WriteStartMember(property); } catch (InvalidOperationException ex) when (/* DuplicateMember */) { /* report duplicate property in the XAML source */ }

Prevention

When it happens

Trigger: A XAML node stream (or the producer building it) emits WriteStartMember/WriteEndMember for the same XamlProperty twice inside one markup-extension object, e.g. duplicate attributes in markup extension usage like {x:Static A=1, A=2}.

Common situations: Hand-written or generated XAML with a duplicated property in a markup extension; custom XAML writers that don't deduplicate members; code generators emitting both an explicit and default member assignment.

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/5aea78c2ffee39d3. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlMarkupExtensionWriter.cs:136

                    // the prefix is not found and curly syntax has no way of defining a prefix
                    return string.Empty; // what we return here is not important, since Failed has set to be true
                }
            }

            return prefix;
        }

        private void CheckMemberForUniqueness(Node objectNode, XamlMember property)
        {
            if (!settings.AssumeValidInput)
            {
                if (objectNode.Members is null)
                {
                    objectNode.Members = new XamlPropertySet();
                }
                else if (objectNode.Members.Contains(property))
                {
                    throw new InvalidOperationException(SR.Format(SR.XamlMarkupExtensionWriterDuplicateMember, property.Name));
                }

                objectNode.Members.Add(property);
            }
        }

        public override void WriteStartObject(XamlType type)
        {
            currentState.WriteStartObject(this, type);
        }

        public override void WriteGetObject()
        {
            currentState.WriteGetObject(this);
        }

        public override void WriteEndObject()
        {

View on GitHub (pinned to 81131a70a4)