actualbudget/actual · error

Formula must start with =

Error message

Formula must start with =

What it means

executeFormulaSync evaluates rule action formulas via HyperFormula, which requires formulas in spreadsheet syntax. If the formula string is empty or does not start with '=', it cannot be parsed as a formula, so the function throws immediately before building the HyperFormula instance.

Source

Thrown at packages/loot-core/src/server/rules/action.ts:301

      for (const value of Object.values(typedNode)) {
        if (typeof value === 'object' && value !== null) {
          walk(value);
        }
      }
    };

    walk(ast);
    return variables;
  }

  executeFormulaSync(
    formula: string,
    transaction: Partial<TransactionForRules>,
  ): unknown {
    let hfInstance: ReturnType<typeof HyperFormula.buildEmpty> | null = null;

    if (!formula || !formula.startsWith('=')) {
      throw new Error('Formula must start with =');
    }

    try {
      hfInstance = HyperFormula.buildEmpty({
        licenseKey: 'gpl-v3',
        language: 'enUS',
        dateFormats: ['DD/MM/YYYY', 'YYYY-MM-DD', 'YYYY/MM/DD'],
        context: {
          balanceOfPrefetch: transaction['_balanceOfPrefetched'] ?? new Map(),
        },
      });

      const sheetName = hfInstance.addSheet('Sheet1');
      const sheetId = hfInstance.getSheetId(sheetName);

      if (sheetId === undefined) {
        throw new Error('Failed to create sheet');
      }

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Ensure the formula string begins with '=' (e.g. '=1+2', '=date(today)') before executing the rule
  2. Normalize input when saving the rule: prepend '=' if missing or reject at save time
  3. Verify the rule's valueIsFormula/conditions flags so plain values aren't routed to the formula evaluator

Example fix

// before
const formula = input.trim(); // "1+2"
// after
const formula = input.trim().startsWith('=') ? input.trim() : '=' + input.trim();
Defensive patterns

Strategy: validation

Validate before calling

if (!formula || !formula.startsWith('=')) throw new Error('Formula must start with =');
executeFormulaSync(formula, transaction);

Type guard

function isFormula(value: unknown): value is string {
  return typeof value === 'string' && value.trim().startsWith('=');
}

Try / catch

try {
  const result = executeFormulaSync(formula, transaction);
} catch (e) {
  if (e instanceof Error && e.message === 'Formula must start with =') {
    // treat input as a plain value or re-prompt the user
  } else throw e;
}

Prevention

When it happens

Trigger: A rule action (set/change value with a formula) whose stored formula is '' or lacks the leading '=' — e.g. user typed '1+2' or 'A1*2' without '=', or a value/formula toggle mixed up plain values with formulas.

Common situations: Users typing plain numbers or expressions into formula fields; migrated/legacy rules where the '=' prefix was stripped; form code saving the raw input without normalization.

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/0bc8fed1e667ed07. Report an issue: GitHub.