Unity-Technologies/UnityCsReference · error · InvalidOperationException

FindItem failed: root item has not been created yet

Error message

FindItem failed: root item has not been created yet

What it means

Thrown by FindItem (a private helper used by GetAncestors and GetDescendantsThatHaveChildren) when rootItem is null. FindItem traverses the tree starting from rootItem to locate an item by id; without a root the tree has not been built and the search is invalid.

Source

Thrown at Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControl.cs:608

            return parentsAbove.ToArray();
#pragma warning restore UA2001
        }

        // Used to expand children recursively below an item
        protected virtual IList<TIdentifier> GetDescendantsThatHaveChildren(TIdentifier id)
        {
            // Default behavior assumes complete tree
            HashSet<TIdentifier> parentsBelow = new HashSet<TIdentifier>();
            TreeViewUtility<TIdentifier>.GetParentsBelowItem(FindItem(id), parentsBelow);
#pragma warning disable UA2001 // The Banned API Analyzer produces compile errors for any new Linq code. This pre-existing usage has been suppressed, but should be rewritten if possible.
            return parentsBelow.ToArray();
#pragma warning restore UA2001
        }

        TreeViewItem<TIdentifier> FindItem(TIdentifier id)
        {
            if (rootItem == null)
                throw new InvalidOperationException("FindItem failed: root item has not been created yet");

            return TreeViewUtility<TIdentifier>.FindItem(id, rootItem);
        }

        // Selection
        protected virtual bool CanMultiSelect(TreeViewItem<TIdentifier> item) => CanMultiSelectInternal(item);

        internal virtual bool CanMultiSelectInternal(TreeViewItem<TIdentifier> item)
        {
            return true; // default behavior
        }

        // Renaming
        protected virtual bool CanRename(TreeViewItem<TIdentifier> item) => CanRenameInternal(item);

        internal virtual bool CanRenameInternal(TreeViewItem<TIdentifier> item)
        {
            return false; // Default to false so user have to enable renaming if wanted

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Ensure treeView.Reload() has been called so rootItem is populated before any id-based lookup.
  2. Override BuildRoot to always return a valid root item.
  3. Avoid calling GetAncestors/GetDescendantsThatHaveChildren during the initial BuildRoot call itself.

Example fix

// before
var parents = treeView.GetParentsBelow(someId); // rootItem null

// after
treeView.Reload();
var parents = treeView.GetParentsBelow(someId);
Defensive patterns

Strategy: validation

Validate before calling

treeView.Reload();
// rootItem is now populated; FindItem-based calls are safe

Prevention

When it happens

Trigger: Calling GetParentsBelow or related methods that invoke FindItem before BuildRoot/Reload has populated rootItem; BuildRoot returned null on the previous fetch.

Common situations: Calling GetAncestors/GetDescendantsThatHaveChildren in a custom override before the data source has built the tree; calling these methods right after construction without Reload.

Related errors


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/ea8d3f3c43239d7d. Report an issue: GitHub.