dotnet/wpf · error · TimeoutException

ERROR_TIMEOUT (1460)

ERROR_TIMEOUT (1460)

Error message

TimeoutException

What it means

A Win32 GetLastError value of ERROR_TIMEOUT (1460) after a native operation is deliberately converted to a TimeoutException, unless the caller explicitly opts to ignore timeouts. This signals that a native interop call (typically SendMessageTimeout or a service request) did not complete within its allotted time.

Solutions

  1. Investigate and fix the hang in the target application's UI thread (the real fix).
  2. Retry the operation after a short delay if the target is expected to become responsive.
  3. Increase the native timeout used in the call (e.g. SendMessageTimeout parameters) if the operation is legitimately slow.
  4. Catch TimeoutException and treat the target as unresponsive: kill/restart or surface a diagnostic.

Example fix

// before
var value = busyElement.GetCurrentPropertyValue(ValuePattern.ValueProperty); // throws TimeoutException

// after
try
{
    var value = busyElement.GetCurrentPropertyValue(ValuePattern.ValueProperty);
}
catch (TimeoutException)
{
    logger.Warn("Target window unresponsive; retrying once after 2s");
    Thread.Sleep(2000);
    var value = busyElement.GetCurrentPropertyValue(ValuePattern.ValueProperty);
}
Defensive patterns

Strategy: retry

Validate before calling

if (!responseWindow.Responding)
    throw new SkipScenarioException($"Window '{responseWindow.Title}' is hung");

Type guard

static bool IsResponsive(IntPtr hwnd)
{
    // smoke-test the target UI thread with a fast timeout before real calls
    var ok = SendMessageTimeout(hwnd, WM_NULL, IntPtr.Zero, IntPtr.Zero,
        SMTO_ABORTIFHUNG, 1000, out _);
    return ok != IntPtr.Zero;
}

Try / catch

const int MaxAttempts = 3;
for (int i = 1; ; i++)
{
    try { result = element.GetCurrentPropertyValue(prop); break; }
    catch (TimeoutException) when (i < MaxAttempts) { Thread.Sleep(500 * i); }
}

Prevention

When it happens

Trigger: Calling UIAutomation proxy paths that use SendMessageTimeout/native timeouts (e.g. querying a busy window, fetching a property) where the target UI thread is blocked and the timeout elapses.

Common situations: Target application's UI thread hung (long synchronous work, modal wait); automating a window in a different session or elevated process that cannot respond; slow startup of the automated app.

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/511a876e4f1c6a02. Report an issue: GitHub.

Appendix: source

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

        private static void EvaluateSendMessageTimeoutError(int error)
        {
            EvaluateSendMessageTimeoutError(error, false);
        }

        private static void EvaluateSendMessageTimeoutError(int error, bool ignoreTimeout)
        {
            // SendMessageTimeout Function
            // If the function fails or times out, the return value is zero. To get extended error information,
            // call GetLastError. If GetLastError returns zero, then the function timed out.
            // NOTE: The GetLastError after a SendMessageTimeout my also be an ERROR_TIMEOUT depending on the
            // message.

            // 1460 This operation returned because the timeout period expired. ERROR_TIMEOUT
            if (error == 0 || error == 1460)
            {
                if (!ignoreTimeout)
                {
                    throw new TimeoutException();
                }
            }
            else
            {
                ThrowWin32ExceptionsIfError(error);
            }
        }

        private static Rect[] GetTitlebarRectsXP(IntPtr hwnd)
        {
            Debug.Assert(System.Environment.OSVersion.Version.Major < 6);

            UnsafeNativeMethods.TITLEBARINFO tiDL;
            if (!Misc.ProxyGetTitleBarInfo(hwnd, out tiDL))
            {
                return null;
            }

View on GitHub (pinned to 81131a70a4)