dotnet/wpf · critical · OutOfMemoryException
ERROR_NOT_ENOUGH_MEMORY (8) / ERROR_OUTOFMEMORY (14)
ERROR_NOT_ENOUGH_MEMORY (8) / ERROR_OUTOFMEMORY (14)
Error message
OutOfMemoryException
What it means
The Win32 error mapper throws OutOfMemoryException when GetLastError is 8 (ERROR_NOT_ENOUGH_MEMORY) or 14 (ERROR_OUTOFMEMORY). The underlying Win32 UI call failed because the system or the target process could not allocate memory, and the mapper converts that native condition into the .NET OutOfMemoryException.
Solutions
- Free memory / reduce memory pressure on both the client and the target process, then retry
- Look for leaks in long-running automation loops (cached elements, providers, handles never released)
- Restart the target application if its process is exhausted (common for 32-bit targets)
- Catch OutOfMemoryException from UIA calls and retry after a delay rather than crashing the harness
Example fix
// before
var result = NativeCall(hwnd); // native error 8/14 -> OutOfMemoryException
// after
try
{
var result = NativeCall(hwnd);
}
catch (OutOfMemoryException)
{
GC.Collect();
Thread.Sleep(500); // allow target process to recover
result = NativeCall(hwnd); // retry
} Defensive patterns
Strategy: retry
Validate before calling
// Check available memory before heavy automation runs:
var gc = GC.GetGCMemoryInfo();
if (gc.MemoryLoadBytes > threshold) { FreeResources(); } Try / catch
for (int i = 0; i < 3; i++) { try { return NativeCall(hwnd); } catch (OutOfMemoryException) { Thread.Sleep(1000); GC.Collect(); } } throw; Prevention
- Dispose UIA elements/providers promptly in long-running loops
- Monitor memory of both client and target processes during automation
- Prefer 64-bit target processes to avoid 32-bit address-space exhaustion
- Schedule large automation runs away from peak system memory load
When it happens
Trigger: Win32 accessibility/window calls made by proxies (SendMessage, GetWindowLong-style calls, etc.) failing with native error 8 or 14 — system-wide or per-process memory exhaustion.
Common situations: Automating very large apps or desktops under memory pressure; target process hitting its address-space limit (32-bit processes); leaky automation loops that never release elements.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- ERROR_INVALID_MENU_HANDLE..ERROR_WINDOW_OF_OTHER_THREAD (1401-1408)
- ERROR_INVALID_PARAMETER (87)
- ERROR_NOACCESS (998) / ERROR_ACCESS_DENIED (5)
- ERROR_SEM_TIMEOUT (121) / WAIT_TIMEOUT (258) / ERROR_SERVICE_REQUEST_TIMEOUT (1053) / ERROR_TIMEOUT (1460)
- OutOfMemoryException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/3562ed301b40420b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/Misc.cs:1691
case 1400: // 1400 ERROR_INVALID_WINDOW_HANDLE Invalid window handle.
case 1401: // 1401 ERROR_INVALID_MENU_HANDLE Invalid menu handle.
case 1402: // 1402 ERROR_INVALID_CURSOR_HANDLE Invalid cursor handle.
case 1403: // 1403 ERROR_INVALID_ACCEL_HANDLE Invalid accelerator table handle.
case 1404: // 1404 ERROR_INVALID_HOOK_HANDLE Invalid hook handle.
case 1405: // 1405 ERROR_INVALID_DWP_HANDLE Invalid handle to a multiple-window position structure.
case 1406: // 1406 ERROR_TLW_WITH_WSCHILD Cannot create a top-level child window.
case 1407: // 1407 ERROR_CANNOT_FIND_WND_CLASS Cannot find window class.
case 1408: // 1408 ERROR_WINDOW_OF_OTHER_THREAD Invalid window; it belongs to other thread.
throw new ElementNotAvailableException();
// 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)View on GitHub (pinned to 81131a70a4)