{"record":{"id":"e20a37d124a87d15","repo":"dotnet/wpf","slug":"sr-format-sr-textcompositionmanager-textcompositionhasdone","errorCode":null,"errorMessage":"SR.Format(SR.TextCompositionManager_TextCompositionHasDone, \"composition\")","messagePattern":"SR\\.Format\\(SR\\.TextCompositionManager_TextCompositionHasDone, \"composition\"\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/TextCompositionManager.cs","lineNumber":347,"sourceCode":"        }\n\n        private static bool UnsafeUpdateComposition(TextComposition composition)\n        {\n            ArgumentNullException.ThrowIfNull(composition);\n\n            if (composition._InputManager == null)\n            {\n                throw new ArgumentException(SR.Format(SR.TextCompositionManager_NoInputManager, \"composition\"));\n            }\n\n            if (composition.Stage == TextCompositionStage.None)\n            {\n                throw new ArgumentException(SR.Format(SR.TextCompositionManager_TextCompositionNotStarted, \"composition\"));\n            }\n\n            if (composition.Stage == TextCompositionStage.Done)\n            {\n                throw new ArgumentException(SR.Format(SR.TextCompositionManager_TextCompositionHasDone, \"composition\"));\n            }\n\n            TextCompositionEventArgs textargs = new TextCompositionEventArgs(composition._InputDevice, composition)\n            {\n                RoutedEvent = TextCompositionManager.PreviewTextInputUpdateEvent,\n                Source = composition.Source\n            };\n            return composition._InputManager.ProcessInput(textargs);\n        }\n\n        private static bool UnsafeCompleteComposition(TextComposition composition)\n        {\n            ArgumentNullException.ThrowIfNull(composition);\n\n            if (composition._InputManager == null)\n            {\n                throw new ArgumentException(SR.Format(SR.TextCompositionManager_NoInputManager, \"composition\"));\n            }","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/TextCompositionManager.cs#L329-L365","documentation":"UnsafeUpdateComposition throws ArgumentException when the composition's Stage is TextCompositionStage.Done, i.e. the composition was already completed and cannot be updated further. Completed compositions are terminal in WPF's lifecycle.","triggerScenarios":"Calling TextCompositionManager.UpdateComposition after CompleteComposition (or after PostProcessInput finished the composition).","commonSituations":"Queued update work (e.g. a Dispatcher.BeginInvoke callback) running after the composition completed; asynchronous IME results arriving late for an already-finished composition.","solutions":["Discard updates once Stage == Done; create a new composition for further input.","Check composition.Stage before calling UpdateComposition and skip terminal compositions.","Order the calls strictly: Start → Update* → Complete, with no late updates after Complete."],"exampleFix":"// before\nTextCompositionManager.CompleteComposition(composition);\nTextCompositionManager.UpdateComposition(composition); // throws\n// after\nTextCompositionManager.CompleteComposition(composition);\n// further text requires a new composition","handlingStrategy":"validation","validationCode":"if (composition.Stage == TextCompositionStage.Done) return; // composition is finished; ignore late updates","typeGuard":"static bool CanUpdate(TextComposition c) => c != null && c.Stage == TextCompositionStage.Started;","tryCatchPattern":"try { TextCompositionManager.UpdateComposition(composition); } catch (ArgumentException ex) { /* composition already done; drop the update */ }","preventionTips":["Cancel pending async/queued updates when a composition completes.","Treat Stage == Done as terminal everywhere.","Prefer creating a new composition for post-completion input."],"tags":["wpf","text-composition","lifecycle"],"backgroundTag":"invalid-state-transition","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"}