dotnet/wpf · error

SR.ParserMultiRoot

Error message

SR.ParserMultiRoot

What it means

TreeBuilder.GetRoot builds an object tree from the XAML record reader's root list and requires exactly one root element. When the parsed XAML contains more than one root node, it throws XamlParseException (ParserMultiRoot) because a loose XAML document must have a single root object.

Solutions

  1. Wrap multiple top-level elements in a single container (Grid, StackPanel, etc.)
  2. Trim the XAML so exactly one root element remains
  3. If loading fragments, load each fragment separately

Example fix

// before
<Button/>
<Label/>
// after
<StackPanel>
  <Button/>
  <Label/>
</StackPanel>
Defensive patterns

Strategy: validation

Validate before calling

// before load: ensure a single root
var rootElems = doc.Root.ElementsAfterSelf().ToList();
if (doc.Root.ElementsAfterSelf().Any())
    throw new InvalidOperationException("XAML must contain exactly one root element");

Try / catch

try { var obj = XamlReader.Parse(xaml); }
catch (XamlParseException ex) when (ex.Message.Contains("root")) { /* wrap content in a single container */ }

Prevention

When it happens

Trigger: Loading XAML content with multiple top-level elements (e.g. two sibling elements at document level, or a comment/root mix that yields 2+ records) through XamlReader.Load / TreeBuilder.Build.

Common situations: Copy-pasting several controls into a XAML file without a wrapping container; programmatic XAML generation emitting multiple roots; concatenating XAML fragments.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/TreeBuilder.cs:206

        ///  ParserHooks implementation
        /// </summary>
        internal ParserHooks ParserHooks
        {
            get { return _hooks; }
            set { _hooks = value; }
        }

        /// <summary>
        /// Root element
        /// </summary>
        internal object GetRoot()
        {
            ArrayList roots = RecordReader.RootList;                
            object root = (null == roots || 0 == roots.Count) ? null : roots[0];

            if (root != null && roots.Count > 1)
            {
                throw new XamlParseException(SR.ParserMultiRoot);
            }
            
            return root; 
        }

        /// <summary>
        /// BamlRecordReader used for Loading the Tree
        /// </summary>
        internal BamlRecordReader RecordReader
        {
            get { return _bamlRecordReader; }
            set { _bamlRecordReader = value; }
        }

#endif

#if !PBTCOMPILER
        /// <summary>

View on GitHub (pinned to 81131a70a4)