{"record":{"id":"5b5266e00d3f4702","repo":"stride3d/stride","slug":"the-given-window-is-not-registered-as-a-clipboard-listener","errorCode":null,"errorMessage":"The given {window} is not registered as a clipboard listener.","messagePattern":"The given (.+?) is not registered as a clipboard listener\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation.Wpf/Interop/ClipboardMonitor.cs","lineNumber":67,"sourceCode":"                hwndSource.AddHook(WinProc);\n                // set the window as a viewer\n                hwndNextViewer = NativeHelper.SetClipboardViewer(hwndSource.Handle);\n            });\n        }\n\n        /// <summary>\n        /// Unregisters the given <paramref name=\"window\"/> as a clipboard viewer.\n        /// </summary>\n        /// <param name=\"window\"></param>\n        /// <exception cref=\"ArgumentNullException\">window is <c>null</c></exception>\n        /// <exception cref=\"InvalidOperationException\">window was not previously registered.</exception>\n        public static void UnregisterListener([NotNull] Window window)\n        {\n            if (window == null) throw new ArgumentNullException(nameof(window));\n\n            HwndSource hwndSource;\n            if (!Listeners.TryGetValue(window, out hwndSource))\n                throw new InvalidOperationException($\"The given {window} is not registered as a clipboard listener.\");\n\n            window.Dispatcher.Invoke(() =>\n            {\n                // stop processing window messages\n                hwndSource.RemoveHook(WinProc);\n                // restore the chain\n                NativeHelper.ChangeClipboardChain(hwndSource.Handle, hwndNextViewer);\n            });\n        }\n\n        [CanBeNull]\n        private static HwndSource GetHwndSource([NotNull] Window window)\n        {\n            var handle = new WindowInteropHelper(window).Handle;\n            return handle != IntPtr.Zero ? HwndSource.FromHwnd(handle) : null;\n        }\n\n        private static void OnClipboardContentChanged(IntPtr hwnd)","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation.Wpf/Interop/ClipboardMonitor.cs#L49-L85","documentation":"ClipboardMonitor.UnregisterListener throws this InvalidOperationException when the supplied Window has no entry in the static Listeners dictionary, meaning it was never registered as a clipboard listener (or was already unregistered). The guard exists so unregistering is always paired with a prior RegisterListener call.","triggerScenarios":"Calling ClipboardMonitor.UnregisterListener(window) before calling RegisterListener(window); calling UnregisterListener twice for the same window; the dictionary entry having been cleared elsewhere.","commonSituations":"WPF shutdown/teardown code paths that unregister clipboard hooks defensively without tracking whether registration succeeded; duplicate window close handlers; a window that was recreated so the old instance was never registered.","solutions":["Only call UnregisterListener on windows that were previously passed to RegisterListener","Track registration state with a bool flag and skip unregistering when false","Wrap the call in try-catch for InvalidOperationException during teardown","Use Listeners.ContainsKey(window) to check registration before unregistering"],"exampleFix":"// before\nClipboardMonitor.UnregisterListener(this);\n// after\nif (ClipboardMonitor.IsRegistered(this))\n    ClipboardMonitor.UnregisterListener(this);","handlingStrategy":"try-catch","validationCode":"if (window == null) throw new ArgumentNullException(nameof(window));\n// only unregister if registration was tracked\nif (!isRegistered) return;","typeGuard":"bool IsListenerRegistered(Window w) => w != null && ClipboardMonitor.IsRegistered(w);","tryCatchPattern":"try { ClipboardMonitor.UnregisterListener(window); }\ncatch (InvalidOperationException) { /* never registered - safe to ignore in teardown */ }","preventionTips":["Track registration with a bool set in RegisterListener","Unregister symmetrically to registration in the same lifecycle event","Wrap teardown unregister calls in try-catch","Check window identity: re-registered windows get new instances"],"tags":["wpf","clipboard","interop","invalid-operation"],"backgroundTag":"invalid-state-transition","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}