dotnet/wpf · error · InvalidOperationException

SR.InavalidStartItem

Error message

SR.InavalidStartItem

What it means

In ItemsControlAutomationPeer.FindItemByProperty, if the provided startAfterItem wraps a null Item (i.e. the automation peer has no corresponding data item), the method throws InvalidOperationException(SR.InavalidStartItem). The start-after reference must be a valid realized item in the items collection for index computation.

Solutions

  1. Pass a valid, realized item container (or null to start from the beginning) as startAfterItem.
  2. Re-fetch the starting element after collection changes instead of reusing a cached peer.
  3. Catch InvalidOperationException and restart the search from null startAfterItem.

Example fix

// before
var next = container.FindItemByProperty(stalePeer, prop, value); // stalePeer.Item == null
// after
var next = stalePeer?.Item != null
    ? container.FindItemByProperty(stalePeer, prop, value)
    : container.FindItemByProperty(null, prop, value);
Defensive patterns

Strategy: validation

Validate before calling

if (startAfterItem != null && startAfterItem.Item == null) startAfterItem = null; // restart search from beginning

Type guard

bool IsValidStart(ItemAutomationPeer p) => p is { Item: not null };

Try / catch

try { next = container.FindItemByProperty(start, prop, value); } catch (InvalidOperationException) { next = container.FindItemByProperty(null, prop, value); }

Prevention

When it happens

Trigger: Calling IItemContainerProvider.FindItemByProperty with a startAfterItem AutomationElement/peer whose underlying Item is null — e.g. a disconnected, virtualized, or placeholder peer passed as the search start point.

Common situations: UIA clients iterating with FindItemByProperty chains where a previous result became invalid (item removed or unrealized by virtualization) and the stale peer is passed as startAfterItem.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/ItemsControlAutomationPeer.cs:262

            if (items != null && items.Count > 0)
            {
                ItemAutomationPeer startAfterItem = null;
                if (startAfter != null)
                {
                    // get the peer corresponding to this provider
                    startAfterItem = PeerFromProvider(startAfter) as ItemAutomationPeer;
                    if(startAfterItem == null)
                        return null;
                }

                // startIndex refers to the index of the item just after startAfterItem
                int startIndex = 0;
                if (startAfterItem != null)
                {
                    if (startAfterItem.Item == null)
                    {
                        throw new InvalidOperationException(SR.InavalidStartItem);
                    }

                    // To find the index of the item in items collection which occurs
                    // immidiately after startAfterItem.Item
                    startIndex = items.IndexOf(startAfterItem.Item)+ 1;
                    if (startIndex == 0 || startIndex == items.Count)
                        return null;
                }

                if (propertyId == 0)
                {
                    for (int i = startIndex; i < items.Count; i++)
                    {
                        // This is to handle the case of when dataItems are just plain strings and have duplicates,
                        // only the first occurence of duplicate Items will be returned. It has also been used couple more times below.
                        if (items.IndexOf(items[i]) != i)
                            continue;
                        return (ProviderFromPeer(FindOrCreateItemAutomationPeer(items[i])));

View on GitHub (pinned to 81131a70a4)