{"record":{"id":"726a4d1601bd1e53","repo":"dotnet/wpf","slug":"unrecognized-stroke-in-strokecollectionchangedeventargs","errorCode":null,"errorMessage":"Unrecognized Stroke in StrokeCollectionChangedEventArgs.Removed.","messagePattern":"Unrecognized Stroke in StrokeCollectionChangedEventArgs\\.Removed\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/Renderer.cs","lineNumber":464,"sourceCode":"                // Attach it to the visual tree\n                AttachVisual(visual, buildingStrokeCollection: false);\n            }\n\n            // Deal with removed strokes first\n            foreach (Stroke stroke in removed)\n            {\n                // Verify that the event is in sync with the view\n                StrokeVisual visual = null;\n                if (_visuals.TryGetValue(stroke, out visual))\n                {\n                    // get rid of both the visual and the stroke\n                    DetachVisual(visual);\n                    StopListeningOnStrokeEvents(visual.Stroke);\n                    _visuals.Remove(stroke);\n                }\n                else\n                {\n                    throw new System.ArgumentException(SR.UnknownStroke3);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Stroke Invalidated event handler\n        /// </summary>\n        private void OnStrokeInvalidated(object sender, EventArgs eventArgs)\n        {\n            System.Diagnostics.Debug.Assert(_strokes.IndexOf(sender as Stroke) != -1);\n\n            // Find the visual associated with the changed stroke.\n            StrokeVisual visual;\n            Stroke stroke = (Stroke)sender;\n            if (!_visuals.TryGetValue(stroke, out visual))\n            {\n                throw new System.ArgumentException(SR.UnknownStroke1);\n            }","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/Renderer.cs#L446-L482","documentation":"Renderer.OnStrokesChanged throws ArgumentException (SR.UnknownStroke3) when a Removed notification references a stroke that the Renderer has no visual for. The renderer can only detach visuals for strokes it previously tracked via Added events.","triggerScenarios":"A Stroke in StrokeCollectionChangedEventArgs.Removed was never part of the Renderer's _visuals dictionary — e.g. the stroke was removed from a collection it was never added to (on that renderer), or state was desynchronized.","commonSituations":"Sharing a StrokeCollection across renderers/threads where events were missed, manually rebuilding collections and firing synthetic change args, suspending/resuming event listening causing missed Adds.","solutions":["Keep one StrokeCollection per Renderer and don't mutate it from outside its owner","Ensure the stroke was Added (and the add event processed) before Removing","Avoid synthetic StrokeCollectionChangedEventArgs with strokes the renderer never saw","Re-sync by rebuilding the StrokeCollection from strokes known to the renderer"],"exampleFix":"// before\nargs = new StrokeCollectionChangedEventArgs(new[] { orphanStroke }, new StrokeCollection());\n// after\nif (tracked.Contains(orphanStroke)) { tracked.Remove(orphanStroke); }","handlingStrategy":"validation","validationCode":"// Ensure the stroke belongs to the collection before removing\nif (collection.Contains(stroke)) collection.Remove(stroke);","typeGuard":"bool CanRemoveSafely(StrokeCollection c, Stroke s) => c != null && c.Contains(s);","tryCatchPattern":"try { collection.Remove(stroke); }\ncatch (ArgumentException ex) { logger.LogWarning(ex, \"Stroke not tracked by renderer\"); }","preventionTips":["Keep one StrokeCollection per Renderer","Don't raise synthetic change events with untracked strokes","Process add events before allowing removes","Re-sync renderer state after bulk collection rebuilds"],"tags":["ink","strokes","events","state"],"backgroundTag":"entity-not-found","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"}