handsontable/handsontable · warning

The "data" setting is ignored when "hasExternalDataSource" r

Error message

The "data" setting is ignored when "hasExternalDataSource" returns `true`.

What it means

When a hook/callback named hasExternalDataSource returns true, Handsontable treats data loading as delegated to an external data provider (server-backed), so any static data setting in the same payload cannot be used — it is ignored and this warning tells you why your data array never reached the grid.

Source

Thrown at handsontable/src/core.ts:3625

            themeObject = registerTheme(settings.theme);
          } else {
            themeObject = settings.theme as ThemeBuilder;
          }

          instance.themeManager!.update(themeObject);
          instance.useTheme(instance.themeManager!.getClassName());
        }
      }
    }

    const themeOverridesChanged = applyThemeOverrides(settings, init);

    // Load data or create data map
    if (instance.runHooks('hasExternalDataSource') === true) {
      // When dataProvider is a complete server-backed config, ignore static data, the plugin loads rows.
      if (settings.data) {
        warn('The "data" setting is ignored when "hasExternalDataSource" returns `true`.');
      }

      // Replace the in-memory placeholder only when the update touches init, `data`, or `dataProvider`. Otherwise
      // `updateData([], …)` would empty the grid without a refetch, because DataProvider runs `updatePlugin` only when
      // `dataProvider` is present in this payload.
      const shouldSyncExternalPlaceholderData = init ||
        hasOwnProperty(settings, 'data') ||
        hasOwnProperty(settings, 'dataProvider');

      if (shouldSyncExternalPlaceholderData) {
        dataUpdateFunction([], 'updateSettings');
      } else if (settings.columns !== undefined) {
        datamap.createMap();
        instance.initIndexMappers();
      }

    } else if (settings.data === undefined && tableMeta.data === undefined) {
      dataUpdateFunction(null as unknown as unknown[], 'updateSettings'); // data source created just now

View on GitHub (pinned to 2c365a3291)

Solutions

  1. Remove the data setting from init/updateSettings/updateData when the external data source is active
  2. Or return false from (or remove) the hasExternalDataSource hook if you actually want static data
  3. Keep the static data path and the provider path mutually exclusive in your component logic

Example fix

// before
hot.updateSettings({ data: localRows }); // hook returns true, so ignored

// after
hot.updateData([], { dataProvider }); // or return false from hasExternalDataSource and pass data normally
Defensive patterns

Strategy: validation

Validate before calling

const external = hot.runHooks('hasExternalDataSource') === true;
if (external && settings.data) {
  delete settings.data; // would be ignored anyway
}

Prevention

When it happens

Trigger: Registering a hasExternalDataSource hook returning true (or a DataProvider config that implies it) while also passing data: [...] in init or updateSettings/updateData.

Common situations: Switching a grid from static data to a server-backed data provider but leaving the old data array in the settings object; wrapper components that always pass a data prop while a parent wires up external data loading.

Related errors


AI-assisted analysis of handsontable/handsontable@2c365a3291 (2026-09-01). Data as JSON: /api/errors/f79c515a652e6227. Report an issue: GitHub.