dotnet/wpf · warning · COMException

0x80040200

0x80040200

Error message

SR.TextStore_CONNECT_E_NOCONNECTION

What it means

UnadviseSink throws COMException 0x80040200 (CONNECT_E_NOCONNECTION) when the object passed does not match the currently registered sink (_sink). Per ITextStoreACP semantics, a client may only unadvise the exact sink it advised; unadvising an unknown connection is an error.

Solutions

  1. Refocus the TextBox/RichTextBox to let WPF re-establish the TSF connection cleanly
  2. Avoid destroying/recreating the text control while IME composition is active; dispose/rebuild in a stable focus state
  3. Disable problematic third-party TSF services to test whether they cause mismatched unadvise calls
  4. Environmental HRESULT returned to TSF; app code rarely needs handling beyond robust focus/dispose lifecycle
Defensive patterns

Strategy: try-catch

Try / catch

try { /* TSF teardown path */ } catch (COMException ce) when (ce.ErrorCode == unchecked((int)0x80040200)) { /* connection already gone; ignore or re-advise */ }

Prevention

When it happens

Trigger: TSF calling UnadviseSink with an object reference different from the one previously registered via AdviseSink — e.g. double-unadvise, unadvising after the store reset its sink, or two different TSF clients managing the same text store.

Common situations: TSF connection teardown races during focus changes; stale sink references after the control was recreated; third-party text services mishandling connection lifetime.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/aa81fdf7b93f5f14. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextStore.cs:106

            if (HasSink)
            {
                Marshal.ReleaseComObject(_sink);
            }
            else
            {
                // Start tracking window movement for _sink.
                _textservicesHost.RegisterWinEventSink(this);
            }

            _sink = sink;
        }

        // See msdn's ITextStoreACP documentation for a full description.
        public void UnadviseSink(object obj)
        {
            if (obj != _sink)
            {
                throw new COMException(SR.TextStore_CONNECT_E_NOCONNECTION, unchecked((int)0x80040200));
            }

            Marshal.ReleaseComObject(_sink);
            _sink = null;

            // We don't need to track window movement for this textstore any more.
            // _sink was the only consumer.
            _textservicesHost.UnregisterWinEventSink(this);
        }

        // See msdn's ITextStoreACP documentation for a full description.
        public void RequestLock(UnsafeNativeMethods.LockFlags flags, out int hrSession)
        {
            if (!HasSink)
                throw new COMException(SR.TextStore_NoSink);

            if (flags == 0)
                throw new COMException(SR.TextStore_BadLockFlags);

View on GitHub (pinned to 81131a70a4)