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

  1. If you want full-tree mode: ensure BuildRoot sets root.children (call AddChild or ensure children list is populated, even if empty).
  2. If you want rows-only mode: override BuildRows, GetAncestors, and GetDescendantsThatHaveChildren in your subclass.
  3. 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

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


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