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 wantedView on GitHub (pinned to 225b0fbdb5)
Solutions
- Ensure treeView.Reload() has been called so rootItem is populated before any id-based lookup.
- Override BuildRoot to always return a valid root item.
- 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
- Always call Reload before GetAncestors/GetDescendantsThatHaveChildren.
- Ensure BuildRoot returns a non-null root so rootItem is set.
- Do not call id-lookup methods during initial BuildRoot.
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
- GetCellRect can only be called when 'multiColumnHeader' has
- root is null
- Only call RefreshCustomRowHeights if you have overridden Get
- BuildRoot should set a valid root item.
- TreeView: 'rootItem.children == null'. Did you forget to add
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/ea8d3f3c43239d7d.
Report an issue: GitHub.