dotnet/wpf · error · InvalidOperationException

SR.SetFocusFailed

Error message

SR.SetFocusFailed

What it means

CalendarAutomationPeer.SetFocusCore throws InvalidOperationException(SR.SetFocusFailed) when UI Automation requested keyboard focus but, after the attempt, the focused day button could not be resolved or did not actually receive keyboard focus (focusedButton == null or IsKeyboardFocused is false). It is a post-condition check that the focus operation failed.

Solutions

  1. Ensure the Calendar has keyboard focus and a valid FocusedDate/DisplayMode before calling SetFocus.
  2. Call SetFocus on the Calendar control itself first, then on the specific date peer.
  3. Retry after layout completes (Dispatcher.BeginInvoke at Loaded priority) rather than immediately after changing DisplayMode.
  4. Catch InvalidOperationException in the automation code and retry once focus stabilizes.

Example fix

// before
datePeer.SetFocus(); // may throw if calendar not focused
// after
calendar.Focus();
Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() => datePeer.SetFocus()));
Defensive patterns

Strategy: try-catch

Validate before calling

if (!calendar.IsKeyboardFocused || calendar.FocusedDate == null)
{
    calendar.Focus(); // establish focus before SetFocus on the peer
}

Try / catch

try { datePeer.SetFocus(); }
catch (InvalidOperationException)
{
    calendar.Focus();
    Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() => datePeer.SetFocus()));
}

Prevention

When it happens

Trigger: Calling SetFocus() on a Calendar or DateTimeAutomationPeer child while the calendar is not focused, the focused date's button cannot be created, or focus moved elsewhere between the attempt and the verification.

Common situations: UIA tests calling SetFocus on Calendar dates right after changing DisplayMode; another control stealing focus concurrently; automation running while the calendar is mid-layout or virtualized.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Automation/Peers/CalendarAutomationPeer.cs:197

                if (!owner.Focus())
                {
                    DateTime focusedDate;
                    // Focus should have moved to either SelectedDate or DisplayDate
                    if (owner.SelectedDate.HasValue && DateTimeHelper.CompareYearMonth(owner.SelectedDate.Value, owner.DisplayDateInternal) == 0)
                    {
                        focusedDate = owner.SelectedDate.Value;
                    }
                    else
                    {
                        focusedDate = owner.DisplayDate;
                    }

                    DateTimeAutomationPeer focusedItem = GetOrCreateDateTimeAutomationPeer(focusedDate, owner.DisplayMode, /*addParentInfo*/ false);
                    FrameworkElement focusedButton = focusedItem.OwningButton;

                    if (focusedButton == null || !focusedButton.IsKeyboardFocused)
                    {
                        throw new InvalidOperationException(SR.SetFocusFailed);
                    }
                }
            }
            else
            {
                throw new InvalidOperationException(SR.SetFocusFailed);
            }
        }

        #endregion Protected Methods

        #region InternalMethods

        private DateTimeAutomationPeer GetOrCreateDateTimeAutomationPeer(DateTime date, CalendarMode buttonMode)
        {
            return GetOrCreateDateTimeAutomationPeer(date, buttonMode, /*addParentInfo*/ true);
        }
        

View on GitHub (pinned to 81131a70a4)