dotnet/wpf · error · ElementNotAvailableException

ElementNotAvailableException

Error message

ElementNotAvailableException

What it means

SetItemText begins label editing by sending TVM_EDITLABELW to the tree-view; the returned handle of the in-place edit control is required to set the new text. If the message returns IntPtr.Zero, the edit control was never created (typically because the item handle or tree hwnd was invalid), and an ElementNotAvailableException is thrown.

Solutions

  1. Re-acquire the AutomationElement so the proxy uses a fresh, valid item handle.
  2. Ensure the underlying TreeView has the TVS_EDITLABELS style enabled.
  3. Verify the tree-view hwnd is still alive (control not disposed) before setting the value.
  4. Catch ElementNotAvailableException and retry after the UI settles.

Example fix

// before
item.SetValue("new text"); // stale handle -> ElementNotAvailableException
// after
var fresh = treeView.FindFirst(TreeScope.Descendants, condition);
fresh.SetValue("new text");
Defensive patterns

Strategy: retry

Validate before calling

if (item.Current.FrameworkId != "Win32" || !item.Current.IsEnabled) throw new SkipException("item not settable now");

Type guard

bool IsAlive(AutomationElement e) { try { _ = e.Current.Name; return true; } catch (ElementNotAvailableException) { return false; } }

Try / catch

try { item.SetValue(text); }
catch (ElementNotAvailableException) { item = ReFind(item); item.SetValue(text); }

Prevention

When it happens

Trigger: Calling ValuePattern.SetValue() on a tree-view item proxy when TVM_EDITLABELW fails to return an edit handle — e.g. stale/invalid item handle, the tree-view lacks TVS_EDITLABELS style, or the control was destroyed/re-created.

Common situations: Automating a tree whose items were rebuilt (handles changed) between finding the element and setting its value, or attempting rename on tree views not created with the edit-labels style.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsTreeView.cs:600

            treeItem.Init(item);
            treeItem.mask = NativeMethods.TVIF_TEXT;
            treeItem.cchTextMax = Misc.MaxLengthNameProperty;

            return XSendMessage.GetItemText(hwnd, treeItem);
        }

        private static bool SetItemText(IntPtr hwnd, IntPtr item, string text)
        {
            // TVM_SETITEMW with TVIF_TEXT will not work here.  It does not notify parent of the change.

            // Begins in-place editing of the specified item's text, replacing the text of the item with a single-line
            // edit control containing the text. This message implicitly selects and focuses the specified item.
            IntPtr hwndEdit = Misc.ProxySendMessage(hwnd, NativeMethods.TVM_EDITLABELW, IntPtr.Zero, item);

            if (hwndEdit == IntPtr.Zero)
            {
                // assume that the hwnd was bad
                throw new ElementNotAvailableException();
            }

            // Now set the text to the edit control
            // Note: The lParam of the WM_SETTEXT is NOT a receive parameter. Just used this overloaded version
            // of ProxySendMessage() for convinces.
            if (Misc.ProxySendMessageInt(hwndEdit, NativeMethods.WM_SETTEXT, IntPtr.Zero, new StringBuilder(text)) != 1)
            {
                // Cancel the edit.
                Misc.ProxySendMessage(hwnd, NativeMethods.TVM_ENDEDITLABELNOW, (IntPtr)1, IntPtr.Zero);
                throw new InvalidOperationException(SR.OperationCannotBePerformed);
            }

            // TVM_ENDEDITLABELNOW ends the editing of a tree-view item's label.
            // The wParam indicates whether the editing is canceled without being saved to the label.
            // If this parameter is TRUE, the system cancels editing without saving the changes.
            // Otherwise, the system saves the changes to the label.
            Misc.ProxySendMessage(hwnd, NativeMethods.TVM_ENDEDITLABELNOW, IntPtr.Zero, IntPtr.Zero);

View on GitHub (pinned to 81131a70a4)