dotnet/wpf · error · InvalidOperationException

SR.ExpectedObjectMarkupInfo

Error message

SR.ExpectedObjectMarkupInfo

What it means

While deciding whether a member's content can be emitted as attribute text (IsAttributable), MemberMarkupInfo expects a single child to be either a ValueMarkupInfo or an ObjectMarkupInfo. A child of any other MarkupInfo kind (e.g. MemberMarkupInfo) violates that invariant, so an InvalidOperationException is thrown — an internal state bug in how the member tree was built.

Solutions

  1. Inspect the object graph member (constructor arguments / collection content) that contains the malformed child and restructure it so content is a plain value or object.
  2. Report/fix as an internal invariant violation: dump the object type and member being read when the exception fires.
  3. Work around by simplifying the type's XAML-serializable surface (e.g. use default constructor + property assignment instead of exotic constructor arguments).
Defensive patterns

Strategy: try-catch

Type guard

bool IsAttributableSafe(MemberMarkupInfo m) => m.Children.Count == 0 || m.Children[0] is ValueMarkupInfo || m.Children[0] is ObjectMarkupInfo;

Try / catch

try { attributable = member.IsAttributable; }
catch (InvalidOperationException ex) when (ex.Message.Contains("markup")) { log(memberType); throw; /* internal invariant — surface details */ }

Prevention

When it happens

Trigger: Reading an object graph where a member's Children contains exactly one node that is neither an ObjectMarkupInfo nor a ValueMarkupInfo while evaluating IsAttributable/IsAttributableMarkupExtension (XamlObjectReader.cs:309-311); typically reached via XamlObjectReader over graphs produced with unusual constructor-argument or collection members.

Common situations: Custom XamlDeferringLoader or markup-extension types producing unexpected node shapes; types whose positional-parameter/constructor-argument content is itself a complex property rather than a value or object; internal invariant breakage after framework changes.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlObjectReader.cs:311

                            if (child is ObjectMarkupInfo objectInfo && !objectInfo.IsAttributableMarkupExtension)
                            {
                                Debug.Assert(false); // should never reach here
                                return false;
                            }
                        }

                        return true;
                    }

                    // Non-empty Collections are not attributable
                    if (Children.Count > 1) { return false; }

                    // Empty collections and atoms are attributable
                    if (Children.Count == 0 || Children[0] is ValueMarkupInfo) { return true; }

                    if (Children[0] is not ObjectMarkupInfo r)
                    {
                        throw new InvalidOperationException(SR.ExpectedObjectMarkupInfo);
                    }

                    return r.IsAttributableMarkupExtension;
                }
            }

            public override void FindNamespace(SerializerContext context)
            {
                var member = XamlNode.Member;
                if (MemberRequiresNamespaceHoisting(member))
                {
                    context.FindPrefix(member.PreferredXamlNamespace);
                }

                foreach (var ov in Children)
                {
                    ov.FindNamespace(context);
                }

View on GitHub (pinned to 81131a70a4)