dotnet/wpf · error · InvalidOperationException

SR.ParserCannotReuseXamlReader

Error message

SR.ParserCannotReuseXamlReader

What it means

XamlReader.LoadAsync stores the stream and lazily creates an object writer; a single XamlReader instance cannot run two load operations concurrently or sequentially. If _objectWriter is already set (a previous LoadAsync in progress or completed), the second LoadAsync(Stream, bool) call throws InvalidOperationException(SR.ParserCannotReuseXamlReader).

Solutions

  1. Create a new XamlReader instance for each load operation.
  2. Use the static XamlReader.LoadAsync(stream) overload, which handles instance lifecycle internally.
  3. If retries are needed, instantiate a fresh reader inside the retry loop.

Example fix

// before
_reader = new XamlReader();
var r1 = await _reader.LoadAsync(stream1);
var r2 = await _reader.LoadAsync(stream2); // throws
// after
var r1 = await new XamlReader().LoadAsync(stream1);
var r2 = await new XamlReader().LoadAsync(stream2);
Defensive patterns

Strategy: validation

Validate before calling

// ensure a fresh reader per load; never reuse
if (readerHasBeenUsed) reader = new XamlReader();
var result = await reader.LoadAsync(stream, useRestrictiveXamlReader);

Try / catch

try { return await reader.LoadAsync(stream); }
catch (InvalidOperationException ex) when (ex.Message.Contains("cannot be shared")) { reader = new XamlReader(); return await reader.LoadAsync(stream); }

Prevention

When it happens

Trigger: Calling LoadAsync on the same XamlReader instance a second time — e.g. reusing a cached reader for another stream, or calling LoadAsync again after an earlier load (including one still running).

Common situations: Caching a XamlReader to 'reuse' it across multiple XAML loads, issuing overlapping async loads from UI events, retry logic that calls LoadAsync on the same instance after failure.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

        /// The load operation will be done asynchronously if the
        /// markup specifies x:SynchronousMode="async".
        /// </summary>
        /// <param name="stream">stream for the xml content</param>
        /// <param name="useRestrictiveXamlReader">Whether or not this method should use 
        /// RestrictiveXamlXmlReader to restrict instantiation of potentially dangerous types</param>
        /// <returns>object root generated after xml parsed</returns>
        /// <remarks>
        /// Notice that this is an instance method
        /// </remarks>
        public object LoadAsync(Stream stream, bool useRestrictiveXamlReader)
        {
            ArgumentNullException.ThrowIfNull(stream);
            _stream = stream;

            if (_objectWriter != null)
            {
                // A XamlReader instance cannot be shared across two load operations
                throw new InvalidOperationException(SR.ParserCannotReuseXamlReader);
            }

            return LoadAsync(stream, null, useRestrictiveXamlReader);
        }

        /// <summary>
        /// Reads XAML using the given XmlReader, building an object tree.
        /// The load operation will be done asynchronously if the markup
        /// specifies x:SynchronousMode="async".
        /// </summary>
        /// <param name="reader">Reader for xml content.</param>
        /// <returns>object root generated after xml parsed</returns>
        /// <remarks>
        /// Notice that this is an instance method
        /// </remarks>
        public object LoadAsync(XmlReader reader)
        {

View on GitHub (pinned to 81131a70a4)