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
- Ensure the formula string begins with '=' (e.g. '=1+2', '=date(today)') before executing the rule
- Normalize input when saving the rule: prepend '=' if missing or reject at save time
- 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
- Normalize formula input at save time to always include a leading '='
- Distinguish plain values from formulas with an explicit flag in rule actions
- Validate formulas in the rule editor UI before persisting
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
- Invalid BUDGET_QUERY dimension: ${dimension}
- Failed creating a new rule
- Failed updating the rule
- Invalid --name: must be a non-empty string.
- No update fields provided. Use --name or --offbudget.
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/0bc8fed1e667ed07.
Report an issue: GitHub.