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
- Emit the node stream in the order the deferring writer expects so the template start triggers TemplateStarting and StartDeferredList before objects are written
- Use XamlDeferringWriter/reader pair through the documented SaveXaml/LoadXaml flow instead of hand-driving the writer
- Reset or recreate the DeferredWriter so _mode returns to Off before writing non-template objects
- 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
- Only write objects after the deferring writer entered TemplateDeferring
- Use the standard XamlDeferringReader/Writer flow instead of hand-driving writes
- Keep WriteStartObject/WriteEndObject strictly balanced
- Recreate the writer after any internal exception rather than continuing
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
- SR.Format(SR.MissingCase, _mode.ToString(), methodName)
- SR.Format(SR.MissingCase, _mode.ToString()…
- SR.Format(SR.MissingCase, _mode.ToString()…
- SR.Format(SR.MissingCase, _mode.ToString(), "WriteMember")
- SR.Format(SR.TemplateNotCollected, "WriteEndMember")
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)