{"record":{"id":"392c035aed91213b","repo":"dotnet/wpf","slug":"sr-format-sr-notinthistree-position","errorCode":null,"errorMessage":"SR.Format(SR.NotInThisTree, \"position\")","messagePattern":"SR\\.Format\\(SR\\.NotInThisTree, \"position\"\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextContainer.cs","lineNumber":3215,"sourceCode":"            valuesEnumerator.Reset();\n            while (valuesEnumerator.MoveNext())\n            {\n                properties[count++] = valuesEnumerator.Current.Property;\n            }\n\n            return properties;\n        }\n\n        #region ValidateXXXHelpers\n\n        // Validation for SetValue.\n        private void ValidateSetValue(TextPointer position)\n        {\n            TextElement element;\n\n            if (position.TextContainer != this)\n            {\n                throw new InvalidOperationException(SR.Format(SR.NotInThisTree, \"position\"));\n            }\n\n            position.SyncToTreeGeneration();\n\n            element = position.Parent as TextElement;\n            if (element == null)\n            {\n                throw new InvalidOperationException(SR.NoElement);\n            }\n        }\n\n        #endregion ValidateXXXHelpers\n\n        // Verifies the TextContainer symbol count is in synch with the TextTreeText\n        // character count.\n        private void AssertTreeAndTextSize()\n        {\n            if (Invariant.Strict)","sourceCodeStart":3197,"sourceCodeEnd":3233,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextContainer.cs#L3197-L3233","documentation":"TextContainer.ValidateSetValue verifies that the supplied TextPointer belongs to this text tree before any set-value operation; if position.TextContainer != this it throws InvalidOperationException(NotInThisTree, \"position\"), because positions are only valid within their owning container.","triggerScenarios":"Passing a TextPointer obtained from a different FlowDocument/TextContainer into an operation on another TextContainer (e.g. setting a property value via a position from another document).","commonSituations":"Copy/paste or cross-document editing code reusing TextPointer instances across two RichTextBox/FlowDocument instances; caching a position after the document was swapped.","solutions":["Obtain a fresh TextPointer from the target TextContainer (e.g. targetDocument.ContentStart) instead of reusing one from another document","Verify position.TextContainer == targetContainer before the call","Re-map the position: read the offset/text in the source container and recreate the pointer in the target"],"exampleFix":"// before\ntargetContainer.ValidateSetValue(pointerFromOtherDoc); // wrong tree\n// after\nvar local = targetContainer.CreatePointerAtOffset(computeOffset(pointerFromOtherDoc), LogicalDirection.Forward);\ntargetContainer.ValidateSetValue(local);","handlingStrategy":"validation","validationCode":"bool sameTree = position.TextContainer == targetContainer;","typeGuard":"static bool IsInTree(TextPointer p, TextContainer t) => p != null && p.TextContainer == t;","tryCatchPattern":"try { container.ValidateSetValue(position); } catch (InvalidOperationException) when (!sameTree) { position = container.CreatePointerAtOffset(offset, position.LogicalDirection); }","preventionTips":["Never share TextPointers across FlowDocuments","Recreate positions in the target container for cross-document edits","Assert TextContainer identity before position-based writes"],"tags":["wpf","textpointer","cross-document"],"backgroundTag":"position-not-in-text-tree","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"}