dotnet/wpf · error · InvalidOperationException

SR.CacheRequestNeedCache

Error message

SR.CacheRequestNeedCache

What it means

Misc.ValidateCached throws InvalidOperationException(SR.CacheRequestNeedCache) when a pattern's Cached property is accessed without a cache request having been made. UIA patterns only expose Cached data when the element/pattern was fetched with an active CacheRequest.

Solutions

  1. Retrieve the element/pattern within an active CacheRequest (AutomationElement.FindFirst with cacheRequest, or cacheRequest.GetUpdatedCache) before accessing .Cached.
  2. Use AutomationElement.GetCachedPattern or pass the cache request so the pattern handle carries cached data.
  3. If live data is acceptable, switch to pattern.Current instead of pattern.Cached.

Example fix

// before
var pat = (ValuePattern)element.GetCurrentPattern(ValuePattern.Pattern);
var v = pat.Cached.Value; // throws
// after
var req = new CacheRequest { TreeScope = TreeScope.Element };
req.Add(ValuePattern.Pattern);
var cached = element.FindFirst(TreeScope.Element, req);
var v = ((ValuePattern)cached.GetCachedPattern(ValuePattern.Pattern)).Cached.Value;
Defensive patterns

Strategy: validation

Validate before calling

var req = new CacheRequest(); req.Add(ValuePattern.Pattern);
var el = root.FindFirst(TreeScope.Children, req); // ensures .Cached is valid

Type guard

static bool HasCachedData(AutomationElement el, AutomationPattern p) => el != null && el.GetSupportedPatterns().Contains(p);

Try / catch

try { var v = pat.Cached.Value; }
catch (InvalidOperationException) { var v = ((ValuePattern)element.GetCurrentPattern(ValuePattern.Pattern)).Current.Value; }

Prevention

When it happens

Trigger: Accessing pattern.Cached on a pattern object obtained without a CacheRequest (e.g., GetCurrentPattern instead of GetCachedPattern or FindFirst with a CacheRequest), or with CacheRequest made default not used during retrieval.

Common situations: Developers mixing Current and Cached access: they retrieve patterns without caching options then read .Cached for performance reasons; typical when copying code that used a CacheRequest elsewhere.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/MS/Internal/Automation/Misc.cs:183

        {
            throw new ArgumentException(SR.Format(SR.GenericInvalidArgument, argName));
        }

        // Check that specified condition is true; if not, throw exception
        internal static void ValidateArgument(bool cond, string reason)
        {
            if (!cond)
            {
                throw new ArgumentException(SR.GetResourceString(reason, null));
            }
        }

        // Called by the patterns before accessing .Cache
        internal static void ValidateCached(bool cached)
        {
            if (!cached)
            {
                throw new InvalidOperationException(SR.CacheRequestNeedCache);
            }
        }

        // Called by the patterns before accessing .Current
        internal static void ValidateCurrent(SafePatternHandle hPattern)
        {
            if (hPattern.IsInvalid)
            {
                throw new InvalidOperationException(SR.CacheRequestNeedLiveForProperties);
            }
        }

        // Call IsCriticalException w/in a catch-all-exception handler to allow critical exceptions
        // to be thrown (this is copied from exception handling code in WinForms but feel free to
        // add new critical exceptions).  Usage:
        //      try
        //      {
        //          Somecode();

View on GitHub (pinned to 81131a70a4)