Unity-Technologies/UnityCsReference · error · InvalidOperationException

Only call RefreshCustomRowHeights if you have overridden Get

Error message

Only call RefreshCustomRowHeights if you have overridden GetCustomRowHeight to customize the height of each row.

What it means

Thrown by RefreshCustomRowHeights when the TreeView subclass has not overridden GetCustomRowHeight. The custom row-height system only works when the subclass provides per-row height logic; calling RefreshCustomRowHeights without the override means there are no custom heights to compute.

Source

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

        internal virtual void RowGUIInternal(RowGUIArgs args)
        {
            m_GUI.DefaultRowGUI(args);
        }

        protected virtual void BeforeRowsGUI()
        {
            if (showAlternatingRowBackgrounds)
                m_GUI.DrawAlternatingRowBackgrounds();
        }

        protected virtual void AfterRowsGUI()
        {
        }

        protected virtual void RefreshCustomRowHeights()
        {
            if (!m_OverriddenMethods.hasGetCustomRowHeight)
                throw new InvalidOperationException("Only call RefreshCustomRowHeights if you have overridden GetCustomRowHeight to customize the height of each row.");
            m_GUI.RefreshRowRects(GetRows());
        }

        protected virtual float GetCustomRowHeight(int row, TreeViewItem<TIdentifier> item) => GetCustomRowHeightInternal(row, item);

        internal virtual float GetCustomRowHeightInternal(int row, TreeViewItem<TIdentifier> item)
        {
            return rowHeight;
        }

        protected virtual Rect GetRenameRect(Rect rowRect, int row, TreeViewItem<TIdentifier> item) => GetRenameRectInternal(rowRect, row, item);

        internal virtual Rect GetRenameRectInternal(Rect rowRect, int row, TreeViewItem<TIdentifier> item)
        {
            return m_GUI.DefaultRenameRect(rowRect, row, item);
        }

        protected virtual void CommandEventHandling()

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Override GetCustomRowHeight in your TreeView subclass before calling RefreshCustomRowHeights.
  2. If you do not need custom heights, remove the RefreshCustomRowHeights call and use fixed rowHeight instead.
  3. Verify the override is declared with the correct signature: protected override float GetCustomRowHeight(int row, TreeViewItem<TIdentifier> item).

Example fix

// before
class MyTree : TreeView<int> {
    void OnSomething() { RefreshCustomRowHeights(); } // no override
}

// after
class MyTree : TreeView<int> {
    protected override float GetCustomRowHeight(int row, TreeViewItem<int> item)
        => item.depth == 0 ? 32f : 20f;
    void OnSomething() { RefreshCustomRowHeights(); }
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (m_OverriddenMethods.hasGetCustomRowHeight)
    RefreshCustomRowHeights();

Type guard

static bool HasCustomRowHeightOverride<T>(TreeView<T> tv) => tv.m_OverriddenMethods.hasGetCustomRowHeight; // internal

Prevention

When it happens

Trigger: Calling RefreshCustomRowHeights() in a TreeView subclass that does not override GetCustomRowHeight; calling it in the base TreeView; the override was removed during refactoring but the refresh call was left behind.

Common situations: Copy-pasting TreeView code that includes RefreshCustomRowHeights but omitting the GetCustomRowHeight override; conditional custom-height logic that calls refresh in a branch without the override.

Related errors


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