handsontable/handsontable · warning
Both `rowHeights` and `minRowHeights` are defined in your co
Error message
Both `rowHeights` and `minRowHeights` are defined in your configuration. As one is the alias of the other, only one of them can be used at a time. `rowHeights` will be used as the row height configuration.
What it means
rowHeights and minRowHeights are aliases of the same row-height configuration option. Defining both in one configuration is ambiguous, so Handsontable warns that only rowHeights will take effect and minRowHeights is discarded.
Source
Thrown at handsontable/src/core.ts:3502
if (isDefined(settings.rows)) {
throwWithCause('The "rows" setting is no longer supported. Do you mean startRows, minRows or maxRows?');
}
if (isDefined(settings.cols)) {
throwWithCause('The "cols" setting is no longer supported. Do you mean startCols, minCols or maxCols?');
}
if (isDefined(settings.ganttChart)) {
throwWithCause('Since 8.0.0 the "ganttChart" setting is no longer supported.');
}
warnAboutRemovedOptions(settings as Record<string, unknown>);
// The `columns` option (or the state its function form reads) may change in this call - drop
// getColHeader's index translation cache so it rebuilds against the updated settings.
columnsSettingIndexes = null;
if (isDefined(settings.rowHeights) && isDefined(settings.minRowHeights)) {
warn('Both `rowHeights` and `minRowHeights` are defined in your configuration. ' +
'As one is the alias of the other, only one of them can be used at a time. ' +
'`rowHeights` will be used as the row height configuration.');
}
// eslint-disable-next-line no-restricted-syntax
for (i in settings) {
if (i === 'data' || i === 'language') {
// Do nothing. loadData and language change will be triggered later
} else if (i === 'className') {
setClassName('className', settings.className);
} else if (i === 'tableClassName' && instance.table) {
setClassName('tableClassName', settings.tableClassName);
instance.view._wt.wtOverlays.syncOverlayTableClassNames();
} else if (Hooks.getSingleton().isRegistered(i) || Hooks.getSingleton().isDeprecated(i)) {View on GitHub (pinned to 2c365a3291)
Solutions
- Remove minRowHeights from the configuration and keep only rowHeights
- If both sources must be merged, merge their values into a single rowHeights definition before passing it to Handsontable
- Audit config-merging code for duplicate alias keys
Example fix
// before
new Handsontable(el, { rowHeights: 40, minRowHeights: 30 });
// after
new Handsontable(el, { rowHeights: 40 }); Defensive patterns
Strategy: validation
Validate before calling
if (settings.rowHeights != null && settings.minRowHeights != null) {
delete settings.minRowHeights; // rowHeights wins
} Prevention
- Standardize on one alias (rowHeights) across all config sources
- Deep-merge defaults carefully so aliases never coexist
- Lint or test config objects for mutually exclusive keys
When it happens
Trigger: Passing an init config or updateSettings payload containing both settings.rowHeights and settings.minRowHeights with defined values.
Common situations: Merging config objects from multiple sources (defaults + user prefs) where one source uses the old name and the other the new one; gradual migration where both spellings were kept 'just in case'; spreading props in wrappers that carry both keys.
Related errors
- Both `theme` and `themeName` are defined in your configurati
- Performance tip: Handsontable rendered more than 1000 visibl
- The "${themeName}" theme is enabled, but its stylesheets are
- The `colorScheme` and `density` options require the theme en
- The "data" setting is ignored when "hasExternalDataSource" r
AI-assisted analysis of handsontable/handsontable@2c365a3291 (2026-09-01).
Data as JSON: /api/errors/7bc4e723226045bd.
Report an issue: GitHub.