dotnet/wpf · error · XamlInternalException

SR.Format(SR.TemplateNotCollected, methodName)

Error message

SR.Format(SR.TemplateNotCollected, methodName)

What it means

XamlInternalException with SR.TemplateNotCollected thrown from DeferredWriter.WriteObject when the writer is in DeferringMode.TemplateReady but WriteStartObject/WriteGetObject was called before a template content was collected. In TemplateReady state the writer expects StartDeferredList to be triggered via the template-starting path, not an arbitrary object write.

Solutions

  1. Emit the node stream in the order the deferring writer expects so the template start triggers TemplateStarting and StartDeferredList before objects are written
  2. Use XamlDeferringWriter/reader pair through the documented SaveXaml/LoadXaml flow instead of hand-driving the writer
  3. Reset or recreate the DeferredWriter so _mode returns to Off before writing non-template objects
  4. Wrap in try/catch on XamlInternalException during development to surface ordering bugs early

Example fix

// before
writer.WriteStartObject(type);   // writer in TemplateReady state -> TemplateNotCollected
// after
writer.WriteStartMember(templateMember); // let template start put writer into TemplateStarting first
writer.WriteStartObject(type);
Defensive patterns

Strategy: try-catch

Try / catch

try { deferringWriter.WriteStartObject(type); }
catch (XamlInternalException ex) { log.Error("DeferredWriter invalid state: {0}", ex.Message); /* regenerate stream non-deferred */ }

Prevention

When it happens

Trigger: Writing a XAML node stream into a deferring writer whose _mode == TemplateReady, with WriteStartObject or WriteGetObjection invoked directly — i.e. the node stream does not begin the template content the deferring reader expects (the expected flow is TemplateStarting -> StartDeferredList -> TemplateDeferring).

Common situations: Custom XAML node-stream transformations or rewriters that re-emit nodes around deferred templates (x:XData / ControlTemplate content) in an order that skips the template-collection handshake; piping nodes from a non-deferring reader directly into a deferring writer.

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/6f5031612026d83b. Report an issue: GitHub.

Appendix: source

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

        {
            WriteObject(null, true, "WriteGetObject");
        }

        public override void WriteStartObject(XamlType xamlType)
        {
            WriteObject(xamlType, false, "WriteStartObject");
        }

        private void WriteObject(XamlType xamlType, bool fromMember, string methodName)
        {
            _handled = false;
            switch (_mode)
            {
                case DeferringMode.Off:
                    break;

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

                case DeferringMode.TemplateStarting:
                    StartDeferredList();
                    _mode = DeferringMode.TemplateDeferring;
                    goto case DeferringMode.TemplateDeferring;

                case DeferringMode.TemplateDeferring:
                    if (fromMember)
                    {
                        _deferredWriter.WriteGetObject();
                    }
                    else
                    {
                        _deferredWriter.WriteStartObject(xamlType);
                    }

                    _deferredTreeDepth += 1;
                    _handled = true;

View on GitHub (pinned to 81131a70a4)