{"record":{"id":"d60b3ad60affa4dc","repo":"dotnet/wpf","slug":"sr-format-sr-templatenotcollected-writeendobject","errorCode":null,"errorMessage":"SR.Format(SR.TemplateNotCollected, \"WriteEndObject\")","messagePattern":"SR\\.Format\\(SR\\.TemplateNotCollected, \"WriteEndObject\"\\)","errorType":"exception","errorClass":"XamlInternalException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/InfosetObjects/DeferredWriter.cs","lineNumber":116,"sourceCode":"                    _deferredTreeDepth += 1;\n                    _handled = true;\n                    break;\n\n                default:\n                    throw new XamlInternalException(SR.Format(SR.MissingCase, _mode.ToString(), methodName));\n            }\n        }\n\n        public override void WriteEndObject()\n        {\n            _handled = false;\n            switch (_mode)\n            {\n            case DeferringMode.Off:\n                break;\n\n            case DeferringMode.TemplateReady:\n                throw new XamlInternalException(SR.Format(SR.TemplateNotCollected, \"WriteEndObject\"));\n\n            case DeferringMode.TemplateDeferring:\n                _deferredWriter.WriteEndObject();\n                _handled = true;\n                _deferredTreeDepth -= 1;\n\n                if (_deferredTreeDepth == 0)\n                {\n                    _deferredWriter.Close();\n                    _deferredWriter = null;\n                    _mode = DeferringMode.TemplateReady;\n                }\n\n                break;\n\n            default:\n                throw new XamlInternalException(SR.Format(SR.MissingCase, _mode.ToString(), \"WriteEndObject\"));\n            }","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/InfosetObjects/DeferredWriter.cs#L98-L134","documentation":"XamlInternalException with SR.TemplateNotCollected thrown from DeferredWriter.WriteEndObject when the writer is in DeferringMode.TemplateReady. Ending an object while in TemplateReady state means the writer expected the template content collection to begin, not terminate an object.","triggerScenarios":"WriteEndObject called on a deferring writer whose _mode == TemplateReady — e.g. the node stream closed an object right after the template was armed but before StartDeferredList entered TemplateDeferring, leaving no matching deferred object to end.","commonSituations":"Unbalanced WriteStartObject/WriteEndObject pairs in custom node-stream generators; a skipped object-start due to an earlier TemplateReady error leaving the state machine behind; templates serialized without their opening object nodes.","solutions":["Ensure WriteStartObject/WriteEndObject calls are balanced and that template content begins via the TemplateStarting path before ending objects","Replay the node stream through the standard XamlServices.Save/deferring reader-writer chain rather than hand-emitting","Recreate the DeferredWriter to reset _mode to Off after a failed write sequence","Catch XamlInternalException during template serialization and validate the node stream with a XamlXmlWriter in non-deferring mode first"],"exampleFix":"// before\n// writer in TemplateReady\nwriter.WriteEndObject(); // TemplateNotCollected\n// after\n// emit template content first (TemplateStarting -> TemplateDeferring), then end objects\nwriter.WriteStartObject(type); writer.WriteEndObject(); // balanced inside deferred region","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { deferringWriter.WriteEndObject(); }\ncatch (XamlInternalException ex) { log.Error(\"WriteEndObject in TemplateReady state: {0}\", ex.Message); }","preventionTips":["Verify StartObject/EndObject pairing before entering template regions","Emit template content via the TemplateStarting path before ending objects","Dry-run node streams through XamlXmlWriter to catch imbalance early","Discard and recreate a writer left in TemplateReady after an error"],"tags":["xaml","internal-exception","deferring-writer","state-machine"],"backgroundTag":"internal-invariant-violation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}