dotnet/wpf · error · XamlInternalException

SR.Format(SR.MissingCase, _mode.ToString()…

Error message

SR.Format(SR.MissingCase, _mode.ToString(), "WriteEndObject")

What it means

XamlInternalException with SR.MissingCase thrown from DeferredWriter.WriteEndObject when the deferring mode has no corresponding switch case. The default arm guards against the writer reaching an untracked DeferringMode during an object-end write.

Solutions

  1. Correct the node-stream producer so deferring modes only take the documented transitions
  2. Update to a current .NET/WPF servicing release in case of a known DeferredWriter bug
  3. Capture the _mode value via the exception message and trace which prior write left it unmapped
  4. Catch XamlInternalException at the serialization boundary and fall back to non-deferred serialization
Defensive patterns

Strategy: try-catch

Try / catch

try { deferringWriter.WriteEndObject(); }
catch (XamlInternalException ex) { log.Error("Unhandled DeferringMode in WriteEndObject: {0}", ex.Message); }

Prevention

When it happens

Trigger: WriteEndObject invoked while _mode holds a value not enumerated in the switch — the writer's deferring-mode tracking no longer matches any known state at the time of the object-end write.

Common situations: Custom XAML readers/writers interleaving events that push the mode machine into an unmapped state; framework version mismatch where a mode added elsewhere isn't handled on this path; node streams corrupted by earlier swallowed exceptions.

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/5741ed3e2afb3eee. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/InfosetObjects/DeferredWriter.cs:133

            case DeferringMode.TemplateReady:
                throw new XamlInternalException(SR.Format(SR.TemplateNotCollected, "WriteEndObject"));

            case DeferringMode.TemplateDeferring:
                _deferredWriter.WriteEndObject();
                _handled = true;
                _deferredTreeDepth -= 1;

                if (_deferredTreeDepth == 0)
                {
                    _deferredWriter.Close();
                    _deferredWriter = null;
                    _mode = DeferringMode.TemplateReady;
                }

                break;

            default:
                throw new XamlInternalException(SR.Format(SR.MissingCase, _mode.ToString(), "WriteEndObject"));
            }
        }

        public override void WriteStartMember(XamlMember property)
        {
            _handled = false;
            switch (_mode)
            {
            case DeferringMode.Off:
                if (property.DeferringLoader is not null)
                {
                    _mode = DeferringMode.TemplateStarting;

                    // We assume in WriteValue that this property can never be multi-valued
                    Debug.Assert(!property.IsDirective && !property.IsUnknown);
                }

                break;

View on GitHub (pinned to 81131a70a4)