dotnet/wpf · error · InvalidOperationException
SR.InavalidStartItem
Error message
SR.InavalidStartItem
What it means
DataGridColumnHeadersPresenterAutomationPeer.GetChildrenCore throws InvalidOperationException when the caller passes a startAfterItem automation peer whose underlying Column is null. The peer cannot compute the start index for partial children enumeration, so the operation is rejected as the start item is not backed by a real column.
Solutions
- Ensure the startAfterItem peer comes from a current GetChildren/FindItemByProperty result and still maps to a live DataGridColumn.
- Check startAfterItem.Column != null before passing it as the anchor.
- Catch InvalidOperationException and fall back to enumerating children from the start (pass null anchor).
- Avoid caching column-header automation peers across column collection changes.
Example fix
// before
var anchor = stalePeer; // Column == null after column removal
var item = presenter.FindItemByProperty(anchor, propertyId, value);
// after
if (anchor?.Column != null)
item = presenter.FindItemByProperty(anchor, propertyId, value);
else
item = presenter.FindItemByProperty(null, propertyId, value); Defensive patterns
Strategy: validation
Validate before calling
if (anchor == null || anchor.Column == null)
anchor = null; // search from start instead of using invalid anchor Type guard
bool IsValidAnchor(AutomationPeer p) => p is DataGridColumnHeaderAutomationPeer ch && ch.Column != null;
Try / catch
try { return container.FindItemByProperty(anchor, propertyId, value); }
catch (InvalidOperationException) { return container.FindItemByProperty(null, propertyId, value); } Prevention
- Never cache column-header automation peers across column collection changes
- Refresh anchors after any DataGrid.Columns modification
- Validate the peer's Column before using it as a search anchor
When it happens
Trigger: Calling UIA FindItemByProperty / IItemContainerProvider.FindItemByProperty on the column-headers presenter and passing a startAfterItem peer whose .Column property is null (e.g. a detached or virtualized column-header peer).
Common situations: UIA clients (inspect.exe, test automation frameworks, screen readers) holding a stale automation peer after a DataGrid column was removed or re-created, then using it as the search anchor.
Related errors
- SR.InavalidStartItem
- SR.DataGrid_AutomationInvokeFailed
- SR.DataGridRow_CannotSelectRowWhenCells
- SR.PropertyNotSupported
- Can only call SelectAll when CanSelectMultipleItems is true.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/e1bab7f07e8765e4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/DataGridColumnHeadersPresenterAutomationPeer.cs:185
if (items != null && items.Count > 0)
{
DataGridColumnHeaderItemAutomationPeer startAfterItem = null;
if (startAfter != null)
{
// get the peer corresponding to this provider
startAfterItem = PeerFromProvider(startAfter) as DataGridColumnHeaderItemAutomationPeer;
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 column items collection which occurs
// immidiately after startAfterItem.Item
startIndex = items.IndexOf(startAfterItem.Column) + 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)