dotnet/wpf · error · InvalidOperationException

SR.CachedPropertyNotRequested

Error message

SR.CachedPropertyNotRequested

What it means

CachedParent is only populated by a CacheRequest that included TreeScope.Parent. The property detects the internal 'not requested' marker (_cachedParent reference-equals this element) and throws InvalidOperationException so callers don't mistake 'not requested' for a real parent value.

Solutions

  1. Include TreeScope.Parent in the CacheRequest before building the cached element
  2. Use CurrentParent instead of CachedParent when no caching is intended
  3. Activate a CacheRequest (Push/Pop) around the element retrieval

Example fix

// before
var parent = found.CachedParent; // throws
// after
var request = new CacheRequest { TreeScope = TreeScope.Element | TreeScope.Parent };
using (request.Activate())
{
    var found = root.FindFirst(TreeScope.Children, condition);
    var parent = found.CachedParent;
}
Defensive patterns

Strategy: validation

Validate before calling

static CacheRequest ParentCachingRequest() =>
    new CacheRequest { TreeScope = TreeScope.Element | TreeScope.Parent };

Type guard

bool HasCachedParent(AutomationElement e) => e is AutomationElement el && !ReferenceEquals(el.CachedParentSafe(), el); // wrap non-throwing accessor

Try / catch

try { var parent = e.CachedParent; }
catch (InvalidOperationException) { parent = e.Current.ParentFallback(); }

Prevention

When it happens

Trigger: Reading element.CachedParent when the element was obtained without a cache request, or with a CacheRequest whose TreeScope did not include Parent (e.g. TreeScope.Element or TreeScope.Children only).

Common situations: Accessing .Cached* properties on elements returned from FindFirst/FindAll without adding the required scope; switching from Current* to Cached* properties without setting up AutomationElement.RootElement.CachedParent-style requests.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/AutomationElement.cs:1033

        /// Returns the parent of this element, with respect to the TreeFilter
        /// condition of the CacheRequest that was active when this AutomationElement
        /// was obtained.
        /// 
        /// Throws InvalidOperationException if the parent was not previously requested
        /// in a CacheRequest.
        /// 
        /// Can return null if the specified element has no parent - eg. is the root node.
        /// </remarks>
        public AutomationElement CachedParent
        {
            get
            {
                // this is used as a marker to indicate 'not requested'
                // - used since null is a valid value for parent, but this can never be.
                // Use (object) case to ensure we just do a ref check here, not call .Equals
                if ((object)_cachedParent == (object)this)
                {
                    throw new InvalidOperationException(SR.CachedPropertyNotRequested);
                }

                return _cachedParent;
            }
        }

        /// <summary>
        /// Returns the cached children of this AutomationElement
        /// </summary>
        /// <remarks>
        /// Returns a collection of children of this element, with respect to the TreeFilter
        /// condition of the CacheRequest that was active when this AutomationElement
        /// was obtained.
        /// 
        /// Throws InvalidOperationException if children or descendants were not previously requested
        /// in a CacheRequest.
        /// 
        /// Can return an empty collection if this AutomationElement has no children.

View on GitHub (pinned to 81131a70a4)