actualbudget/actual · error
Failed to create sheet
Error message
Failed to create sheet
What it means
After building a HyperFormula instance, the code adds a worksheet named 'Sheet1' and resolves its numeric sheet id via getSheetId. If the returned id is undefined — meaning the sheet wasn't actually created or the name lookup failed — evaluation cannot proceed and it throws 'Failed to create sheet'.
Source
Thrown at packages/loot-core/src/server/rules/action.ts:318
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');
}
const fieldValues: Partial<TransactionForRules> & {
today: string;
account_name: string;
category_name: string;
} = {
...transaction,
today: currentDay(),
account_name: transaction._account_name || '',
category_name: transaction._category_name || '',
};
for (const key of Object.keys(fieldValues)) {
if (key === '_balanceOfPrefetched') {
continue;
}
let cellValue: string | number | boolean;View on GitHub (pinned to d4334cb6e6)
Solutions
- Always build a fresh HyperFormula.buildEmpty() instance per evaluation so 'Sheet1' cannot pre-exist
- Check the return value of addSheet and use the returned sheet name for getSheetId
- Pin/verify the HyperFormula version and its API contract for addSheet/getSheetId
Example fix
// before
const sheetName = hfInstance.addSheet('Sheet1');
const sheetId = hfInstance.getSheetId(sheetName);
// after
const created = hfInstance.addSheet('Sheet1');
const sheetId = hfInstance.getSheetId(created ?? 'Sheet1');
if (sheetId === undefined) throw new Error('Failed to create sheet'); Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
try {
const result = executeFormulaSync(formula, transaction);
} catch (e) {
if (e instanceof Error && e.message === 'Failed to create sheet') {
// retry once with a fresh HyperFormula instance or surface an internal error
} else throw e;
} Prevention
- Never share/reuse HyperFormula instances across evaluations
- Keep the HyperFormula dependency version pinned and reviewed on upgrades
- Report this as a bug if it occurs with a fresh instance — it indicates a library-level failure
When it happens
Trigger: addSheet('Sheet1') failing or returning a name whose id lookup yields undefined, typically when a sheet named 'Sheet1' already exists in the instance or HyperFormula returns an unexpected result (internal/library-level failure).
Common situations: Reusing a HyperFormula instance where 'Sheet1' already exists; HyperFormula version changes altering addSheet/getSheetId return behavior; running out of resources in constrained environments.
Related errors
- Formula error: ${cellValue.type}
- Formula error: ${cellValue.message}
- Failed to create sheet
- Invalid BUDGET_QUERY dimension: ${dimension}
- Formula must start with =
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/c82fd45d43e8dd44.
Report an issue: GitHub.