Skip to content

[data grid] Fix crash in getRowValue when colDef is undefined#22838

Merged
LukasTy merged 11 commits into
mui:masterfrom
LukasTy:claude/flamboyant-pascal-86fd19
Jun 24, 2026
Merged

[data grid] Fix crash in getRowValue when colDef is undefined#22838
LukasTy merged 11 commits into
mui:masterfrom
LukasTy:claude/flamboyant-pascal-86fd19

Conversation

@LukasTy

@LukasTy LukasTy commented Jun 16, 2026

Copy link
Copy Markdown
Member

Fixes #22831

What

getRowValue (gridRowsUtils.ts) read colDef.field before its own if (!colDef) guard, so the guard was dead code. Any caller passing an undefined colDef crashed with:

TypeError: Cannot read properties of undefined (reading 'field')

This reorders the guard so the dereference is safe, hardens the row-spanning getCellValue the same way, documents the premium aggregation value-getter closure (now safe via the guarded getRowValue), and applies the same guard to the Premium getRowValue/getRowFormattedValue overrides.

Why / how it is reachable

A colDef looked up by field is undefined when the field is not in the current column lookup -- e.g. getColumn(field) returning undefined, which flows into getRowValue via getCellParams -> getCellParamsForRow. The minimal reproduction:

apiRef.current.getCellParams(1, 'does-not-exist')

The fix lives in getRowValue so it holds regardless of which caller trips it.

DataGridPro routes through the community getRowValue, so it is covered by the community fix. DataGridPremium overrides getRowValue/getRowFormattedValue (for aggregation results) and dereferenced colDef.field before delegating, so it still crashed on the same input -- this PR guards those overrides too.

Note on the premium aggregation closure: adding if (!column) continue there would have been wrong, as it would move the crash to the valueGetters[field]! call site. With the guard in place, getRowValue(row, undefined) returns undefined, which is already filtered out when aggregating.

Testing

Added regression tests calling getCellParams(id, unknownField) for DataGrid (cells.DataGrid.test.tsx), DataGridPro (rows.DataGridPro.test.tsx), and DataGridPremium (aggregation.DataGridPremium.test.tsx). Verified red -> green for each: they throw the reported TypeError before the fix and pass after.

Verified: x-data-grid jsdom suite, rowSpanning browser tests, full x-data-grid-premium unit suite, TypeScript (community + pro + premium), ESLint, and Prettier all pass.

`getRowValue` read `colDef.field` before its own `if (!colDef)` guard, so
the guard was dead code and any caller passing an undefined `colDef` threw
`TypeError: Cannot read properties of undefined (reading 'field')`.

This is reachable whenever a `colDef` is looked up by field and the field
is not in the current column lookup (e.g. `getColumn(field)` returning
`undefined` via `getCellParams`). Reorder the guard so the dereference is
safe, and harden the row-spanning `getCellValue` the same way.

The premium aggregation value-getter closure also passes a possibly
`undefined` column to `getRowValue`; with the guard in place it now
returns `undefined` (filtered out when aggregating) instead of crashing.

Closes mui#22831

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@code-infra-dashboard

code-infra-dashboard Bot commented Jun 16, 2026

Copy link
Copy Markdown

Deploy preview

https://deploy-preview-22838--material-ui-x.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid 🔺+5B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 🔺+5B(0.00%) 🔺+1B(0.00%)
@mui/x-data-grid-premium 🔺+19B(0.00%) 🔺+6B(0.00%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)
@mui/x-license 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@LukasTy LukasTy added type: bug It doesn't behave as expected. scope: data grid Changes related to the data grid. plan: Pro Impact at least one Pro user. labels Jun 16, 2026
@LukasTy LukasTy self-assigned this Jun 16, 2026
LukasTy and others added 3 commits June 16, 2026 23:49
…alue`

The Premium overridable param methods dereferenced `colDef.field` before
delegating to the (now guarded) community `getRowValue`, so
`DataGridPremium.getCellParams(id, unknownField)` still crashed with
`TypeError: Cannot read properties of undefined (reading 'field')`.

Guard `colDef` in both overrides so the Premium path is as tolerant as the
community one. `DataGridPro` was already covered since it does not override
these methods. Add regression tests for both Pro and Premium.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@LukasTy LukasTy added the plan: Premium Impact at least one Premium user. label Jun 17, 2026
@LukasTy
LukasTy marked this pull request as ready for review June 17, 2026 11:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a runtime crash in the Data Grid params/value resolution path when a column definition lookup returns undefined (e.g. apiRef.current.getCellParams(id, 'unknown-field')), by ensuring colDef is guarded before dereferencing colDef.field. It also adds regression tests across Community/Pro/Premium, and hardens related row-spanning and Premium aggregation paths that indirectly rely on getRowValue.

Changes:

  • Reorders/strengthens colDef guarding in getRowValue (community) and related row-spanning getCellValue.
  • Adds regression tests ensuring getCellParams(id, unknownField) does not throw in Community, Pro, and Premium.
  • Guards Premium getRowValue/getRowFormattedValue overrides and documents why aggregation value-getters may receive an undefined column.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/x-data-grid/src/hooks/features/rows/gridRowsUtils.ts Moves the !colDef guard before field dereference in getRowValue to prevent crashes.
packages/x-data-grid/src/hooks/features/rows/gridRowSpanningUtils.ts Adds a colDef guard to row-spanning getCellValue to avoid null dereferences.
packages/x-data-grid-premium/src/hooks/features/rows/useGridParamsOverridableMethods.ts Adds colDef guards to Premium params overrides to avoid dereferencing colDef.field when missing.
packages/x-data-grid-premium/src/hooks/features/aggregation/createAggregationLookup.ts Documents that aggregation can see undefined columns and relies on guarded getRowValue.
packages/x-data-grid/src/tests/cells.DataGrid.test.tsx Adds a regression test for getCellParams(id, unknownField) in Community.
packages/x-data-grid-pro/src/tests/rows.DataGridPro.test.tsx Adds a regression test for getCellParams(id, unknownField) in Pro.
packages/x-data-grid-premium/src/tests/aggregation.DataGridPremium.test.tsx Adds a regression test for getCellParams(id, unknownField) in Premium.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/x-data-grid/src/hooks/features/rows/gridRowsUtils.ts
Address review feedback: type the internal `getRowValue`/`getCellValue`
`colDef` params as `GridColDef | undefined` so the guards are no longer dead
code against the type, and return `undefined` directly in the Premium
`getRowValue` override instead of delegating with an `undefined` colDef.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Comment on lines +22 to +24
if (!colDef) {
return undefined;
}

@MBilalShafi MBilalShafi Jun 19, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kind of a Nitpick:

Just like this guard, would it be better to also add a guard on the community API method, that makes sure that the method is not invoked at all if the necessary params (in this case colDef) are not available?

Also, the interface GridParamsApi['getRowValue'] doesn't correctly point out the expected input type for colDef param that supports undefined too now. But changing it may touch the public API interface (possibly be considered a BC too).

So probably either of:

  1. Add guards on both the API entry points (premium and community), remove the redundant one from the util, and make sure all the entry points to this util go through the API.
  2. Add a guard only on the util with the updated TS interface that reflects that, and the API methods pass the param without any gate-keeping.

Having guards at both levels feels a little bit redundant.

Wdyt?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, went with your option 2.

Option 1 isn't quite feasible: the util getRowValue has callers that intentionally bypass the API, most notably row spanning's getCellValue, which calls it directly during state initialization (before apiRef.current.getRowValue is ready -- there's a comment to that effect), plus row grouping and the Premium filter value-getter config. So the util has to stay the defensive layer.

So the single guard now lives in the util (typed colDef: GridColDef | undefined), and the Premium overrides just pass through via optional chaining (colDef?.field) instead of duplicating the guard. The aggregation result selector now accepts an undefined field and returns null for it, which is correct -- no column means no aggregation result, and it falls through to the guarded util.

I propose leaving the GridParamsApi['getRowValue'] interface as GridColDef to avoid the BC concern you also raised; the internal util is the safety net.

LukasTy and others added 3 commits June 22, 2026 12:59
Address review feedback: instead of guarding `colDef` in both the Premium
param overrides and the community util, keep the single guard in the util
(which is also called directly, e.g. during row-spanning state init, so it
must stay defensive) and let the Premium overrides pass through via optional
chaining. The aggregation result selector now accepts an `undefined` field
and returns `null` for it.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@LukasTy
LukasTy requested a review from MBilalShafi June 23, 2026 11:17

@michelengelen michelengelen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@LukasTy
LukasTy merged commit 8367e95 into mui:master Jun 24, 2026
21 checks passed
@LukasTy
LukasTy deleted the claude/flamboyant-pascal-86fd19 branch June 24, 2026 11:34
mbrookes pushed a commit to mbrookes/mui-x that referenced this pull request Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plan: Premium Impact at least one Premium user. plan: Pro Impact at least one Pro user. scope: data grid Changes related to the data grid. type: bug It doesn't behave as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[data grid] crash when adding column

4 participants