dotnet/wpf · error · XamlInternalException
SR.Format(SR.TemplateNotCollected, "WriteMember")
Error message
SR.Format(SR.TemplateNotCollected, "WriteMember")
What it means
XamlInternalException with SR.TemplateNotCollected thrown from DeferredWriter.WriteStartMember when the writer is in DeferringMode.TemplateReady. Starting a member in TemplateReady state means the template content was never collected through the TemplateStarting -> StartDeferredList transition, so member writes are invalid.
Solutions
- Emit the member writes only after the writer entered TemplateDeferring (i.e. after StartDeferredList ran)
- Drive serialization through XamlDeferringReader/XamlDeferringWriter rather than calling WriteStartMember manually in TemplateReady
- Reset the writer (new DeferredWriter) so _mode is Off for non-template content
- Add a pre-write assertion/check of the deferring mode in custom writer code
Example fix
// before writer.WriteStartMember(member); // _mode == TemplateReady -> TemplateNotCollected // after // let the template-start path run StartDeferredList first (TemplateStarting -> TemplateDeferring) writer.WriteStartMember(member); // now valid inside deferred region
Defensive patterns
Strategy: try-catch
Try / catch
try { deferringWriter.WriteStartMember(member); }
catch (XamlInternalException ex) { log.Error("WriteStartMember in TemplateReady state: {0}", ex.Message); } Prevention
- Only write members inside the deferred region (TemplateDeferring active)
- Do not hand-call WriteStartMember around template boundaries
- Reset the writer state machine after template errors
- Assert the deferring mode in custom writer code during development
When it happens
Trigger: WriteStartMember called while _mode == TemplateReady — for instance the template-start node (x:ClassModifier-style template content start) was consumed into TemplateReady but the next write was a plain member write instead of entering the deferred list.
Common situations: Custom node-stream rewriters that drop or reorder the node that triggers StartDeferredList; writing template content with a raw writer API without going through the deferring reader's template flow; test harnesses emitting synthetic node streams around templates.
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, methodName)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/05bc0a0d69779d00.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/InfosetObjects/DeferredWriter.cs:154
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;
case DeferringMode.TemplateReady:
throw new XamlInternalException(SR.Format(SR.TemplateNotCollected, "WriteMember"));
case DeferringMode.TemplateDeferring:
_deferredWriter.WriteStartMember(property);
_handled = true;
break;
default:
throw new XamlInternalException(SR.Format(SR.MissingCase, _mode.ToString(), "WriteMember"));
}
}
public override void WriteEndMember()
{
_handled = false;
switch (_mode)
{
case DeferringMode.Off:
break;View on GitHub (pinned to 81131a70a4)