dotnet/wpf · error · TimeoutException

ERROR_SEM_TIMEOUT (121) / WAIT_TIMEOUT (258) / ERROR_SERVICE_REQUEST_TIMEOUT (1053) / ERROR_TIMEOUT (1460)

ERROR_SEM_TIMEOUT (121) / WAIT_TIMEOUT (258) / ERROR_SERVICE_REQUEST_TIMEOUT (1053) / ERROR_TIMEOUT (1460)

Error message

TimeoutException

What it means

The Win32 error mapper throws TimeoutException when the native call fails with a timeout-class error: ERROR_SEM_TIMEOUT (121), WAIT_TIMEOUT (258), ERROR_SERVICE_REQUEST_TIMEOUT (1053), or ERROR_TIMEOUT (1460). The target window's UI thread did not answer within the permitted period, so the automation operation times out instead of hanging or returning garbage.

Solutions

  1. Increase the automation timeout settings and retry — a busy UI thread often becomes responsive
  2. Diagnose the target app's UI thread (dump the process, check for message-loop hangs, debugger breakpoints)
  3. Dismiss modal states (drag loops, menus, dialogs) before issuing further automation calls
  4. Catch TimeoutException per operation and re-walk/re-acquire the element rather than reusing the stale provider

Example fix

// before
var value = element.GetCurrentPropertyValue(AutomationElement.NameProperty); // may throw TimeoutException
// after
try
{
    var value = element.GetCurrentPropertyValue(AutomationElement.NameProperty);
}
catch (TimeoutException)
{
    // target UI thread not responding: retry with backoff or restart target
    Thread.Sleep(retryDelay);
    value = ReacquireAndGet();
}
Defensive patterns

Strategy: retry

Validate before calling

// Probe responsiveness before real calls:
if (!IsHungAppWindow(hwnd)) { Proceed(hwnd); } else { WaitForResponsive(hwnd, timeout); }

Try / catch

for (int attempt = 0; attempt < maxRetries; attempt++)
{
    try { return DoUiaOperation(); }
    catch (TimeoutException) { Thread.Sleep(backoff); ReacquireElement(); }
}
throw new TimeoutException("target UI thread unresponsive");

Prevention

When it happens

Trigger: Cross-process SendMessage/accessibility calls to a window whose UI thread is blocked, hung, or in a modal loop, returning native timeout errors 121/258/1053/1460.

Common situations: Target app frozen (not pumping messages); a modal drag/resize or debug break blocking the UI thread; slow startup under load; target app waiting on a dialog the automation did not notice.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/Misc.cs:1701

                // We're getting this in AMD64 when calling RealGetWindowClass; adding this code
                // to allow the DRTs to pass while we continue investigation.
                case 87:    //   87 ERROR_INVALID_PARAMETER
                    throw new ElementNotAvailableException();

                case 8:     //    8 ERROR_NOT_ENOUGH_MEMORY         Not enough storage is available to process this command.
                case 14:    //   14 ERROR_OUTOFMEMORY               Not enough storage is available to complete this operation.
                    throw new OutOfMemoryException();

                case 998:   //  998 ERROR_NOACCESS                  Invalid access to memory location.
                case 5:     //    5 ERROR_ACCESS_DENIED
                    throw new InvalidOperationException();

                case 121:   //  121 ERROR_SEM_TIMEOUT               The semaphore timeout period has expired.
                case 258:   //  258 WAIT_TIMEOUT                    The wait operation timed out.
                case 1053:  // 1053 ERROR_SERVICE_REQUEST_TIMEOUT   The service did not respond to the start or control request in a timely fashion.
                case 1460:  // 1460 ERROR_TIMEOUT                   This operation returned because the timeout period expired.
                    throw new TimeoutException();

                default:
                    // Not sure how to map the reset of the error codes so throw generic Win32Exception.
                    throw new Win32Exception(errorCode);
            }
        }

        internal static bool UnhookWinEvent(IntPtr winEventHook)
        {
            // There is no indication in the Windows SDK documentation that UnhookWinEvent()
            // will set an error to be retrieved with GetLastError
            return UnsafeNativeMethods.UnhookWinEvent(winEventHook);
        }

        internal static bool UnionRect(out NativeMethods.Win32Rect rcDst, ref NativeMethods.Win32Rect rc1, ref NativeMethods.Win32Rect rc2)
        {
            bool result = SafeNativeMethods.UnionRect(out rcDst, ref rc1, ref rc2);
            int lastWin32Error = Marshal.GetLastWin32Error();

View on GitHub (pinned to 81131a70a4)