handsontable/handsontable · warning

<caught error message from HyperFormula addNamedExpression()

Error message

<caught error message from HyperFormula addNamedExpression()> (e instanceof Error ? e.message : String(e))

What it means

When the Formulas plugin registers named expressions through HyperFormula's `addNamedExpression()`, any thrown error (name conflict, invalid expression, bad scope) is caught and emitted as a console warning instead of interrupting grid initialization. The affected named expression is not available to formulas.

Source

Thrown at handsontable/src/plugins/formulas/engine/register.ts:274

export function registerNamedExpressions(
  engineInstance: HyperFormulaEngine, namedExpressions: Record<string, unknown>[]
) {
  if (namedExpressions) {
    engineInstance.suspendEvaluation();

    namedExpressions.forEach((namedExp: Record<string, unknown>) => {
      const {
        name,
        expression,
        scope,
        options
      } = namedExp;

      try {
        engineInstance.addNamedExpression(name, expression, scope, options);

      } catch (e) {
        warn(e instanceof Error ? e.message : String(e));
      }
    });

    engineInstance.resumeEvaluation();
  }
}

/**
 * Sets up the sheet to work on. An existing sheet is reused; a new one is added only when there is
 * nothing to reuse.
 *
 * @param {object} engineInstance The engine instance.
 * @param {string} [sheetName] The sheet name to use. When omitted (or `null`), a new sheet is added.
 * @returns {string}
 */
export function setupSheet(engineInstance: HyperFormulaEngine, sheetName?: string | null) {
  if (sheetName === undefined || sheetName === null) {
    return engineInstance.addSheet();

View on GitHub (pinned to 2c365a3291)

Solutions

  1. Check the warned message for the exact HyperFormula error.
  2. Use unique names per scope, or remove the existing named expression before re-adding.
  3. Confirm `scope` refers to an existing sheet index (omit for global scope).
  4. Recreate the engine instance instead of reusing one that already holds the named expressions.

Example fix

// before
namedExpressions: [{ name: 'TAX', expression: '=0.23', scope: 5 }] // sheet 5 missing
// after
namedExpressions: [{ name: 'TAX', expression: '=0.23' }] // global scope, no collision
Defensive patterns

Strategy: try-catch

Validate before calling

if (namedExpressions.some(ne => ne.scope !== undefined && ne.scope >= engine.countSheets())) {
  throw new Error('named expression scope out of range');
}

Try / catch

try { engine.addNamedExpression(name, expression, scope, options); } catch (e) { console.warn('addNamedExpression failed:', e.message); }

Prevention

When it happens

Trigger: Providing `namedExpressions: [{ name, expression, scope, options }]` where the name already exists in the engine/scope, the expression is invalid, or the scope sheet id does not exist.

Common situations: Re-initializing the grid (or hot reload) and re-adding the same named expression to a persistent shared engine; referencing a scope sheet index beyond the sheet count; typos in expression syntax.

Related errors


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