dotnet/wpf · error · COMException

SR.TextStore_BadLockFlags

Error message

SR.TextStore_BadLockFlags

What it means

TextStore.RequestLock throws this COMException when a TSF (Text Services Framework) client requests a document lock with a flags value of 0 (no TS_LF_READ/TS_LF_WRITE bits set). A lock request must ask for at least read or write access; a zero-flag request is meaningless and rejected immediately. The HRESULT is E_INVALIDARG-style failure surfaced back to the IME/text service via hrSession.

Solutions

  1. Fix the calling text service to pass a valid lock mask (TS_LF_READ, TS_LF_WRITE, or both) to RequestLock.
  2. If you own interop wrappers, ensure the LockFlags enum value is preserved across the marshaling boundary and not defaulted to 0.
  3. Reproduce with a specific IME installed; update or replace the offending IME/text service.

Example fix

// before (caller side)
LockFlags flags = 0;
store.RequestLock(flags, out hrSession);
// after
LockFlags flags = LockFlags.TS_LF_READ | LockFlags.TS_LF_WRITE;
store.RequestLock(flags, out hrSession);
Defensive patterns

Strategy: validation

Validate before calling

if ((lockFlags & (LockFlags.TS_LF_READ | LockFlags.TS_LF_WRITE)) == 0) { /* fix flags before calling RequestLock */ }

Try / catch

try { store.RequestLock(flags, out hrSession); } catch (COMException ex) { /* handle bad lock flags */ }

Prevention

When it happens

Trigger: A text service calls ITextStoreACP::RequestLock with dwLockFlags == 0, i.e. neither TS_LF_READ nor TS_LF_WRITE nor TS_LF_READWRITE requested.

Common situations: Buggy or third-party IME/text services that zero-initialize the lock flags struct and forget to OR in the desired access bits; interop marshaling code passing an empty enum value.

Understand the failure class

Background: "unknown output mode", "invalid value for flag", "expects true/false": fixing invalid flag value errors in CLI tools — this error's family across 24 libraries.

Related errors


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

Appendix: source

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

                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)