Skip to content

Latest commit

 

History

History
233 lines (194 loc) · 50.7 KB

File metadata and controls

233 lines (194 loc) · 50.7 KB

TanStack Table remaining open-issue audit

Generated 2026-07-30 from a fresh scan of the 110 issues still open in TanStack/table, cross-referenced against the two 2026-07-26 audits (issues-gpt.md, issues-claude.md) and re-verified against current v9 alpha source (post module-level-fns perf refactor; 9.0.0-beta.61 era, which includes PR #6458 merged 2026-07-29).

Result

  • 61 issues can close now without a new PR — including 2 newly fixed by #6458 and 2 duplicates of a canonical selection issue.
  • 49 issues should remain open: 10 verified & urgent, 37 valid, 2 needing investigation.
  • 115 of the 225 issues from the July 26 audits were closed between then and today; zero new issues have been filed since. Every currently open issue was covered by both prior audits.
  • Where the two audits disagreed (27 issues), each was re-adjudicated against current source: 9 resolved to close, 18 to keep open.
  • 17 already-open PRs target keep-open issues (see table below); landing or porting them to alpha would clear roughly a third of the keep-open list.

Audit baseline

  • v9 baseline: 9.0.0-beta.61 (source branch includes the module-level-fns perf refactor)
  • Method: 9 parallel investigation agents; per-issue checks of issue threads (activity after 2026-07-26), current packages/table-core/src source, and open/merged PRs. No fixes applied, no PRs opened, no repo files modified.
  • Verdict rule: disagreements between the prior audits were resolved by re-reading current source; "Verified & Urgent" means the defect was re-confirmed live in current code on a default or documented path.

Summary

Category Count Recommended action
Was fixed in V9 14 Close; behavior is correct in current alpha (2 fixed by #6458 this week).
Wrong Library Direction 32 Close with the documented/headless-library boundary.
Junk Issue 11 Close as support-only, malformed, user error, or unreproducible-v8-era.
Couldn't Reproduce 2 Close unless a current minimal reproduction is supplied.
Duplicate 2 Close as duplicates of canonical #6049.
Verified & Urgent 10 Keep open and prioritize.
Valid 37 Keep open; many have fix PRs waiting to land or port.
Maybe & Needs Investigation 2 Keep only for additional triage.
Total 110 61 close candidates; 49 keep open.

Fix-first priority list

Ranked by user impact. Fixing the top four clusters closes or unblocks ~20 issues.

  1. #6078 — process is not defined crash (Verified & Urgent, high). Raw process.env.NODE_ENV reads survive into the published dist (packages/table-core/dist/utils.js) because tsdown.config.ts has no define; any bundler-less consumer (importmap/CDN) gets a hard ReferenceError, and v9 dropped the v8 UMD escape hatch. PR #6185 targets main only — needs an alpha port.
  2. Global-filter eligibility cluster — canonical #4673 (+ #4783, #4919, #5138). Default getColumnCanGlobalFilter still samples only flatRows[0] and requires string/number, and the AND in column_getCanGlobalFilter means explicit enableGlobalFilter: true can never opt back in — search silently returns nothing. Pending PRs: #6252/#6438 (nullish scan), #6439 (explicit opt-in). One combined fix closes three issues as duplicates.
  3. Parent/child selection reconciliation — canonical #6049 (+ #5116, #5398; close #4878/#5416 as duplicates). Deselecting a descendant never removes the ancestor id, so getIsSelected() and getIsSomeSelected() can both be true and the shipped expanding example renders a parent fully checked with an unselected child. One refactor of table_toggleAllRowsSelected/mutateRowIsSelected plausibly fixes five open issues plus the closed-set #4349 family.
  4. Auto-reset first-run guard — #5968. v9 dropped v8's registered first-run guard: memo fires onAfterUpdate on the first computation, so the very first getRowModel() schedules table_autoResetExpanded/table_autoResetPageIndex, wiping controlled expanded and any initial pageIndex on mount (and table_resetPageIndex(table, true) hard-codes 0, ignoring initialState).
  5. row._valuesCache never invalidated — #4485 / #5363 (high). createCoreRowModel memoizes on [options.data] only, so a new columns/accessorFn silently serves stale values into rendering, sorting, and filtering — the documented "memoize columns" pattern yields wrong data. v8 PR #5582 shows the approach.
  6. #6007 — inNumberRange matches null as 0 (Verified & Urgent, high). No resolveDataValue, so null/''/false coerce to 0 and pass any zero-spanning range; this is the auto-selected default filter for number columns. PR #6313 open.
  7. #5770 — group-column visibility (Valid, high). Explicit columnVisibility: { groupId: false } is ignored; Kevin already approved fixing it in the alpha ("Only in the alpha. Want to limit breaking changes in main.") and the alpha is the only window for this breaking change.

Open PRs to land or port

PR Fixes Status
#6439 #4673/#5138 (explicit enableGlobalFilter opt-in) Open
#6252 / #6438 #4783/#4919 (scan past nullish first row) Open
#6431 #4309 (single-sort replace branch) Open
#6313 #6007 (exclude non-numeric from inNumberRange) Open
#6361 #5987 (maxLeafRowFilterDepth flatRows) Open
#6417 #6081 (refresh custom faceted values) Open
#6443 #5801 (reset expansion on data change) Open (base beta)
#5790 / #6177 #5173 (isSubRowSelected with unselectable children) Open
#6075 #6074 (columnFiltersMeta wipe) Open, targets v8 main — needs alpha port
#5823 #5822 (pinned-row lookup crash) Open since 2024-12, targets v8 — needs alpha port
#6185 #6078 (process.env in dist) Open, targets v8 — needs alpha port
#6186 #6077 (Vue empty-string hydration) Open, targets v8 — needs alpha port
#6116 #6115 (expand-all writes non-expandable ids) Open, targets v8 — needs alpha port
#6184 #6136 (no-op toggleExpanded rerender) Open, targets v8 — needs alpha port
#6176 #6175 (example server.allowedHosts) Open
#5031 #4703-adjacent pageIndex clamp Open, targets v8
#5582 #4485/#5363 (_valuesCache invalidation approach) Open, targets v8 — port concept to alpha

Close now

Was fixed in V9 (14)

Wrong Library Direction (32)

Junk Issue (11)

Couldn't Reproduce (2)

Duplicates (2)

Keep open

Verified & Urgent (10)

  • #4673 — Global filter doesn't run when accessor key points to an objecthigh; canonical for the global-filter cluster. Default getColumnCanGlobalFilter samples only flatRows[0] and requires string/number (globalFilteringFeature.ts:30-37), and the AND in column_getCanGlobalFilter means explicit enableGlobalFilter: true can never override — a custom globalFilterFn is silently skipped. PR #6439 open. This issue exercises both facets (nullish scan + opt-in), so keep it as canonical.
  • #4783 — Global Filter Fails When First Row Value is Undefinedhigh. Same first-row-sampling defect: a column whose row-0 value is undefined/null is silently excluded from global filtering, returning empty search results on the default path. PRs #6252/#6438 open. Closeable as duplicate of #4673 once one fix merges.
  • #4919 — Filter not working if accessorFn returns null for any rowhigh. The column-filter half is fixed in v9 (column_getAutoFilterFn scans past nullish), but the global-filter half persists. Same cluster and pending PRs as #4783.
  • #5173 — row.getIsSomeSelected returning true for row with disabled subrowsmedium. isSubRowSelected (rowSelectionFeature.utils.ts:909-941) still initializes allChildrenSelected = true and never clears it when all children are non-selectable, returning 'all' with zero selected rows and propagating bogus someSelected upward. Two open fix PRs (#5790, #6177) — land one on alpha.
  • #5363 — getValue cache not invalidating when accessorFn is updatedhigh. row_getValue serves row._valuesCache forever and createCoreRowModel memoizes on [options.data] only, so swapping columns/accessorFn silently feeds stale values into rendering, sorting, and filtering. v8 PR #5582 shows the fix approach; same root cause as #4485/#4702.
  • #5822 — Pinning aggregation rows then ungrouping causes a hard errormedium. table_getPinnedRows still calls the throwing table.getRow(rowId, true) unguarded (rowPinningFeature.utils.ts:126), so a pinned synthetic group id crashes getTopRows()/getBottomRows() after ungrouping. Reporter's fix PR #5823 open and unreviewed since 2024-12.
  • #5968 — Invoking table.getRowModel() causes rows to collapsehigh. v9 dropped v8's first-run auto-reset guard: memo fires onAfterUpdate on the first computation and createGroupedRowModel forces rowInputsChanged = true on that first run, so the first getRowModel() schedules table_autoResetExpanded/table_autoResetPageIndex — wiping controlled expanded and any initial pageIndex on mount (table_resetPageIndex(table, true) hard-codes 0, ignoring initialState). Canonical survivor of the #5970/#6025/#6030 cluster (all since closed).
  • #6007 — When using filterVariant: 'range' and filtering with a min value of 0, null values are also included in the resultshigh. filterFn_inNumberRange has no resolveDataValue, so null/''/false coerce to 0 and match any zero-spanning range — and it is the auto-selected default filter for number columns. Sibling inDateRange already does this correctly. PR #6313 open.
  • #6049 — Row Selection: Incorrect Parent Row Selection Behavior with Nested Datahigh; canonical for the selection-reconciliation cluster. Deselecting descendants never removes the ancestor id and row_getIsSelected reads only its own id, so a parent can report getIsSelected() and getIsSomeSelected() true simultaneously; the shipped expanding example renders it fully checked with an unselected child, and getSelectedRowModel() keeps the stale parent. Close #4878/#5416 into this.
  • #6078 — process is not defined when used in Vanilla JS (without Node.js)high. Raw process.env.NODE_ENV reads persist in source (~14 sites) and survive into the published build (packages/table-core/dist/utils.js) because tsdown.config.ts has no define; any bundler-less consumer gets a hard ReferenceError, and v9 dropped the v8 UMD escape hatch. PR #6185 targets v8 main only — needs an alpha fix.

Valid (37)

High priority

Medium priority

Low priority

Maybe & Needs Investigation (2)

  • #5696 — Table using insane amount of memory even with virtualisation when scrollingrow_getAllCells still materializes a Cell per leaf column per row into row._cellsCache (now a WeakMap) retained for the lifetime of a stable columns reference, so column virtualization does not avoid rows×cols cell construction. Prior scratch estimate ~122 B/cell (~470 MB extrapolated at 2000×2000); needs a fresh browser heap profile separating table vs virtual vs renderer cost.
  • #6011 — virtual columns experimental can not scroll smoothly when nearing the end — The repro is this repo's own shipped virtualized-columns-experimental example, so even if the root cause is TanStack Virtual measurement, the fix is plausibly example-side (row virtualizer measureElement changing total height mid-drag). One cheap experiment (fixed row estimateSize or overflow-y: scroll) decides between fixing the example and transferring to the Virtual repo.

Root-cause clusters (updated from the July 26 audits)

# Root cause Open issues Status
1 v9 dropped v8's first-run auto-reset guard; first getRowModel() wipes controlled/initial expanded/pageIndex #5968 (canonical; #5970/#6025/#6030 already closed) Unfixed; table_resetPageIndex(table, true) also ignores initialState
2 Global-filter eligibility decided from flatRows[0]; explicit enableGlobalFilter: true cannot override #4673 (canonical), #4783, #4919, #5138 PRs #6252/#6438/#6439 open
3 row._valuesCache never invalidated when columns/accessorFn change #4485, #5363 (#4702 closed) v8 PR #5582 open; port concept to alpha
4 Parent/child selection never reconciled upward #6049 (canonical), #5116, #5398; close #4878/#5416 as dups Unfixed; one refactor fixes the family
5 column_getAutoSortDir samples flatRows[0] #5147, #5832 Unfixed; sortDescFirst workaround
6 Non-multi sort toggle preserves other sorts on the last-sorted column #4309 (#6070 closed) PR #6431 open
7 Group (non-leaf) columns second-class in visibility/offsets #5497, #5770, #5397 (#4872/#5577 closed as docs-direction) Unfixed; #5770 has maintainer-approved direction
8 v8-targeted fix PRs never ported to alpha #6074, #6077, #6078, #6115, #6136, #5822 Six open PRs against main need alpha ports

Changes vs the July 26 audits

  • #6224 / #6450: were Verified & Urgent in both audits; fixed by PR #6458 (merged 2026-07-29) — useTable now defers controlled-state publication to a layout effect. Close both.
  • #5026 / #4634: same fix family; the 2026-07-27 maintainer comment plus #6458 flips them from open questions to closeable.
  • #6078: was Maybe/Valid; escalated to Verified & Urgent — the process.env reads demonstrably survive into the published v9 dist and there is no workaround.
  • #4994: was Verified & Urgent in the GPT audit; flips to close — the reporter explicitly opted out with autoResetPageIndex: false, and the docs assign reset responsibility to the app; the real clamp gap is tracked by #4703 (closed) and PR #5031.
  • #4878 / #5416: keep-verdicts consolidated into close-as-duplicate of canonical #6049.
  • #5850: GPT's close verdict overturned — Kevin committed in-thread to adding removeRowSelection(ids) to the v9 alpha; the helper does not exist yet.