dotnet/wpf · error · InvalidOperationException

SR.CacheReqestCantModifyWhileActive

Error message

SR.CacheReqestCantModifyWhileActive

What it means

CheckAccess() throws InvalidOperationException when a CacheRequest is modified while it is active. A request is considered active if its refcount (_refCount) is non-zero (i.e., some thread has it pushed on its stack) or if it is the shared CacheRequest.DefaultCacheRequest, which is immutable by design.

Solutions

  1. Create and configure a new CacheRequest instead of modifying the active one
  2. Never mutate CacheRequest.DefaultCacheRequest; clone its settings into a new request
  3. Move all configuration (Add/TreeScope/TreeFilter) before calling Push()/Activate()
  4. Use the using(var act = request.Activate()) pattern and configure properties outside that block
  5. Synchronize across threads so configuration happens only when no thread holds the request

Example fix

// before
using (req.Activate())
{
    req.Add(AutomationElement.NameProperty); // InvalidOperationException: active
}
// after
req.Add(AutomationElement.NameProperty);
using (req.Activate())
{
    var name = element.Cached.Name;
}
Defensive patterns

Strategy: validation

Validate before calling

if (request != CacheRequest.DefaultCacheRequest)
{
    request.TreeScope = ...; request.TreeFilter = ...; // configure before Activate
}
using (request.Activate()) { /* consume cached values only */ }

Try / catch

try { request.Add(prop); } catch (InvalidOperationException) { request = CloneConfigured(request); }

Prevention

When it happens

Trigger: Setting TreeScope, TreeFilter, or AutomationElementMode (or calling Add for a property/pattern) while the request is currently pushed/activated on any thread; attempting to modify CacheRequest.DefaultCacheRequest at any time.

Common situations: Mutating a request inside a CacheRequest.Activate() scope; a long-lived request stored in a static field that other threads have pushed; code trying to add properties to DefaultCacheRequest to widen default caching; races where another thread still holds the request active.

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/a7732aff06729cb6. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/CacheRequest.cs:472

        //
        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods

        // Ensure that this CacheRequest isn't currently in use
        // Must be called within a lock(_instanceLock) to ensure
        // thread consistency
        private void CheckAccess()
        {
            // Make sure this isn't being used by any thread's
            // CacheRequest stacks by using a refcount:
            // (Also check for defaultCacheRequest explicitly, since it
            // is never explicitly added to the stack)
            if (_refCount != 0 || this == DefaultCacheRequest)
            {
                throw new InvalidOperationException(SR.CacheReqestCantModifyWhileActive);
            }
        }

        // Called when state changes - sets _uiaCacheRequest to null
        // to ensure that a clean one is generated next time Push is called
        private void Invalidate()
        {
            _uiaCacheRequest = null;
        }

        #endregion Private Methods


        //------------------------------------------------------
        //
        //  Private Fields
        //
        //------------------------------------------------------

View on GitHub (pinned to 81131a70a4)