{"record":{"id":"7e67972efaa08ee6","repo":"Unity-Technologies/UnityCsReference","slug":"number-of-rows-does-not-match-number-of-row-rects","errorCode":null,"errorMessage":"Number of rows does not match number of row rects. Did you remember to update the row rects when BuildRootAndRows was called? Number of rows: {0}, number of custom row rects: {1}. Falling back to fixed row height.","messagePattern":"Number of rows does not match number of row rects\\. Did you remember to update the row rects when BuildRootAndRows was called\\? Number of rows: (.+?), number of custom row rects: (.+?)\\. Falling back to fixed row height\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlGUI.cs","lineNumber":275,"sourceCode":"                {\n                    base.GetFirstAndLastRowVisible(out firstRowVisible, out lastRowVisible);\n                    return;\n                }\n\n                var rowCount = m_TreeView.data.rowCount;\n                if (rowCount == 0 || Mathf.Approximately(m_TreeView.visibleRect.height, 0.0f))\n                {\n                    firstRowVisible = lastRowVisible = -1;\n                    return;\n                }\n\n                if (rowCount != m_RowRects.Count)\n                {\n                    var errorMessage = string.Format(\n                        \"Number of rows does not match number of row rects. Did you remember to update the row rects when BuildRootAndRows was called? Number of rows: {0}, number of custom row rects: {1}. Falling back to fixed row height.\",\n                        rowCount, m_RowRects.Count);\n                    m_RowRects = null;\n                    throw new InvalidOperationException(errorMessage);\n                }\n\n                float topPixel = m_TreeView.state.scrollPos.y;\n                float heightInPixels = m_TreeView.visibleRect.height;\n\n                int firstVisible = -1;\n                int lastVisible = -1;\n                for (int i = 0; i < m_RowRects.Count; ++i)\n                {\n                    bool visible =  ((m_RowRects[i].y > topPixel && (m_RowRects[i].y < topPixel + heightInPixels))) ||\n                        ((m_RowRects[i].yMax > topPixel && (m_RowRects[i].yMax < topPixel + heightInPixels)));\n\n                    if (visible)\n                    {\n                        if (firstVisible == -1)\n                            firstVisible = i;\n                        lastVisible = i;\n                    }","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/GUI/TreeView/TreeViewControl/TreeViewControlGUI.cs#L257-L293","documentation":"Thrown during visible-row computation (in TreeViewControlGUI) when the number of rows (rowCount) does not match the number of custom row rects (m_RowRects.Count). This means BuildRows changed the row count but RefreshRowRects was not called to recompute the per-row Rect array, leaving the geometry inconsistent. The message says it 'falls back' but the code actually nulls m_RowRects and throws.","triggerScenarios":"Overriding GetCustomRowHeight and changing row data (Reload/BuildRows) without calling RefreshCustomRowHeights afterward; BuildRows returning a different count than when rects were last computed; rows added/removed between reload and render.","commonSituations":"Dynamic TreeView where items are added/removed at runtime without calling Reload + RefreshCustomRowHeights; custom BuildRows that filters rows differently each call.","solutions":["Call treeView.Reload() then treeView.RefreshCustomRowHeights() whenever the underlying data changes.","Ensure BuildRows and GetCustomRowHeight are consistent in the row count they assume.","Override BuildRows to call RefreshCustomRowHeights internally if rows change, or ensure m_RowRects is rebuilt in BuildRows."],"exampleFix":"// before\n// data changed, rows differ from rects\nOnDataChanged();\n\n// after\nOnDataChanged();\ntreeView.Reload();\ntreeView.RefreshCustomRowHeights(); // recomputes m_RowRects to match rows","handlingStrategy":"validation","validationCode":"treeView.Reload();\ntreeView.RefreshCustomRowHeights(); // keeps m_RowRects in sync with row count","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call Reload + RefreshCustomRowHeights after any data change.","Keep BuildRows and GetCustomRowHeight consistent in row count.","Recompute custom row rects whenever rows are added or removed."],"tags":["unity","treeview","custom-row-height","rowrect","sync","invalid-operation"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}