dotnet/wpf · error · XamlInternalException
SR.Format(SR.TemplateNotCollected, "WriteValue")
Error message
SR.Format(SR.TemplateNotCollected, "WriteValue")
What it means
XamlInternalException thrown by XamlDeferringWriter.WriteValue when the writer is in TemplateReady deferring mode, meaning a deferred template's node list exists but has not been collected/loaded yet, so writing a value at that point would corrupt the node stream. System.Xaml throws this because template deferral requires StartObject/EndObject transitions before values can be accepted.
Solutions
- Fix the node-stream ordering: ensure WriteStartObject/WriteEndObject (template collection) transitions occur before calling WriteValue in a deferred-template context.
- If the intent is to write values into the deferred template, use the deferred node list (XamlNodeList.Writer) rather than the outer deferring writer.
- Do not interleave direct Write* calls with deferred template collection on the same writer; complete one mode before switching.
- Treat this as a bug in the calling writer implementation — XamlInternalException indicates a violated internal protocol, not user input error.
Example fix
// before (wrong: WriteValue while template is ready but not collected)
writer.WriteStartObject(templateType);
writer.WriteValue("some value"); // throws XamlInternalException
// after
writer.WriteStartObject(templateType);
writer.WriteEndObject(); // complete the template collection transition first
writer.WriteValue("some value"); Defensive patterns
Strategy: validation
Validate before calling
if (deferringWriter.Mode == DeferringMode.TemplateReady)
throw new InvalidOperationException("Complete template collection transitions before WriteValue."); Type guard
static bool CanWriteValue(XamlDeferringWriter w) => w.Mode != DeferringMode.TemplateReady;
Try / catch
try { writer.WriteValue(v); }
catch (XamlInternalException ex) { LogProtocolBug(ex); throw; } // never swallow: indicates caller bug Prevention
- Never interleave direct Write* calls with deferred-template collection on one writer.
- Route template-body nodes through the XamlNodeList writer, not the outer deferring writer.
- Complete StartObject/EndObject transitions before values.
- Treat XamlInternalException as a caller-protocol bug, not recoverable input.
When it happens
Trigger: Calling WriteValue on a XamlDeferringWriter (obtained via XamlObjectWriterSettings/XamlXmlWriter template deferral) while _mode == DeferringMode.TemplateReady — i.e. after a deferred template has been prepared but before its node collection phase has started or completed.
Common situations: Custom XAML writers/readers that hand-craft node streams around markup-extension templates; feeding nodes out of order to a deferring writer; mixing a XamlNodeList-producing pipeline with direct Write* calls on the same 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
- NotImplementedException(SR.MissingCaseXamlNodes)
- NotSupportedException(SR.MissingCaseXamlNodes)
- SR.Format(SR.MissingCase, _mode.ToString(), methodName)
- SR.Format(SR.MissingCase, _mode.ToString()…
- SR.Format(SR.MissingCase, _mode.ToString()…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/108fb7db26fc46ec.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/InfosetObjects/DeferredWriter.cs:196
_deferredWriter.WriteEndMember();
_handled = true;
break;
default:
throw new XamlInternalException(SR.Format(SR.MissingCase, _mode.ToString(), "WriteEndMember"));
}
}
public override void WriteValue(object value)
{
_handled = false;
switch (_mode)
{
case DeferringMode.Off:
break;
case DeferringMode.TemplateReady:
throw new XamlInternalException(SR.Format(SR.TemplateNotCollected, "WriteValue"));
case DeferringMode.TemplateStarting:
// This handles the case of SM template; V object; EM
Debug.Assert(_deferredTreeDepth == 0);
if (value is XamlNodeList)
{
_deferredList = (XamlNodeList)value;
_mode = DeferringMode.TemplateReady;
_handled = true;
}
else
{
StartDeferredList();
_mode = DeferringMode.TemplateDeferring;
goto case DeferringMode.TemplateDeferring;
}
break;View on GitHub (pinned to 81131a70a4)