Unity-Technologies/UnityCsReference · critical · InvalidOperationException
TreeView: 'rootItem.children == null'. Did you forget to add
Error message
TreeView: 'rootItem.children == null'. Did you forget to add children? If you intend to only create the list of rows (not the full tree) then you need to override: BuildRows, GetAncestors and GetDescendantsThatHaveChildren.
What it means
Thrown by ValidateRootItem when rootItem.children is null AND the subclass has not overridden BuildRows. Unity's TreeView can operate in two modes: full-tree (BuildRoot populates children) or rows-only (override BuildRows/GetAncestors/GetDescendantsThatHaveChildren). Having null children without the rows-only overrides is an inconsistent configuration.
Source
Thrown at Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlDataSource.cs:45
// Clear root item to ensure client gets a call to BuildRoot every time Reload is called
m_RootItem = null;
base.ReloadData();
}
void ValidateRootItem()
{
if (m_RootItem == null)
{
throw new NullReferenceException("BuildRoot should set a valid root item.");
}
if (m_RootItem.depth != -1)
{
Debug.LogError("BuildRoot should ensure the root item has a depth == -1. The visible items start at depth == 0.");
m_RootItem.depth = -1;
}
if (m_RootItem.children == null && !m_Owner.m_OverriddenMethods.hasBuildRows)
{
throw new InvalidOperationException("TreeView: 'rootItem.children == null'. Did you forget to add children? If you intend to only create the list of rows (not the full tree) then you need to override: BuildRows, GetAncestors and GetDescendantsThatHaveChildren.");
}
}
public override void FetchData()
{
// Set before BuildRoot and BuildRows so we can call GetRows in them without recursion
m_NeedRefreshRows = false;
// Root
if (m_RootItem == null)
{
m_RootItem = m_Owner.BuildRoot();
ValidateRootItem();
}
// Rows
m_Rows = m_Owner.BuildRows(m_RootItem);
if (m_Rows == null)View on GitHub (pinned to 225b0fbdb5)
Solutions
- If you want full-tree mode: ensure BuildRoot sets root.children (call AddChild or ensure children list is populated, even if empty).
- If you want rows-only mode: override BuildRows, GetAncestors, and GetDescendantsThatHaveChildren in your subclass.
- Initialize root.children to an empty list rather than leaving it null: root.children = new List<TreeViewItem<TIdentifier>>();
Example fix
// before
protected override TreeViewItem<int> BuildRoot()
{
return new TreeViewItem<int>(0, -1, "root"); // children null
}
// after (full-tree mode)
protected override TreeViewItem<int> BuildRoot()
{
var root = new TreeViewItem<int>(0, -1, "root");
root.children = new List<TreeViewItem<int>>();
// add children...
return root;
} Defensive patterns
Strategy: validation
Validate before calling
var root = new TreeViewItem<int>(0, -1, "root"); root.children = new List<TreeViewItem<int>>(); // never null return root;
Type guard
static bool HasConsistentChildren<T>(TreeViewItem<T> root, bool hasBuildRows)
=> root.children != null || hasBuildRows; Prevention
- Always set root.children to at least an empty list in full-tree mode.
- If using rows-only mode, override BuildRows, GetAncestors, and GetDescendantsThatHaveChildren.
- Decide on tree vs rows-only mode early and implement the required overrides.
When it happens
Trigger: Overriding BuildRoot to return a root with children == null (default) without also overriding BuildRows, GetAncestors, and GetDescendantsThatHaveChildren; switching from full-tree to rows-only mode but forgetting the required overrides.
Common situations: Building a lazy-loaded TreeView that only computes visible rows; a data source where the root legitimately has no children yet but BuildRows was not overridden.
Related errors
- visibleColumns should should not be set to an empty array. A
- Setting columnIndexForTreeFoldouts can only be set when usin
- root is null
- FindItem failed: root item has not been created yet
- BuildRoot should set a valid root item.
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/cea3b7c3e464e24b.
Report an issue: GitHub.