dotnet/wpf · warning · COMException
SR.TextStore_NoSink
Error message
SR.TextStore_NoSink
What it means
RequestLock, part of the TSF ITextStoreACP contract, asks the sink for a document lock. If no sink has ever been advised (HasSink is false), the store throws COMException SR.TextStore_NoSink because there is no one to request the lock from. This indicates RequestLock was invoked without a preceding successful AdviseSink.
Solutions
- Ensure the text control is focused and TSF connection completed (AdviseSink succeeded) before input/IME activity; refocus the control to re-establish the sink
- Delay or guard IME-dependent operations until the store has an active sink
- Disable faulty third-party TSF/IME components that call RequestLock out of order
- Environmental HRESULT to TSF; typically no app-level catch needed, but log it if IME input breaks
Defensive patterns
Strategy: try-catch
Try / catch
try { /* IME-driven path */ } catch (COMException ce) when (ce.Message.Contains("NoSink") || (uint)ce.ErrorCode == 0xFFFFFFFF) { RefocusTextControl(); } Prevention
- Ensure AdviseSink completed before IME input begins
- Refocus controls to re-establish TSF sink after failures
- Guard composition-dependent code on window activation state
When it happens
Trigger: TSF/IME calling RequestLock on the TextStore before (or after) the ITextStoreACPSink was advised/unadvised — e.g. lock request arriving during connection setup, after teardown, or when AdviseSink failed earlier (see CONNECT_E errors).
Common situations: IME composition starting before TSF finished advising the sink; focus races between window activation and text store registration; third-party TSF services making out-of-order calls.
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/e1731e64694c0b8a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextStore.cs:121
{
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);
bool isReplayingIMEChanges = (_replayingIMEChangeReentrancyCount > 0);
if (IsTracing)
{
IMECompositionTracer.Trace(this, IMECompositionTraceOp.BRequestLock,
"f:", flags,
"lf:", _lockFlags,
"icr:", _replayingIMEChangeReentrancyCount,
"ric:", isReplayingIMEChanges,
"tcr:", _textChangeReentrencyCount,
"paf:", _pendingAsyncLockFlags);
if (_replayingIMEChangeReentrancyCount != 0)
{
IMECompositionTracer.Mark(new System.Diagnostics.StackTrace(true));View on GitHub (pinned to 81131a70a4)