actualbudget/actual · error

Failed to create sheet

Error message

Failed to create sheet

What it means

evaluateFormulaWithContext builds a temporary HyperFormula instance to evaluate a single formula. It calls hfInstance.addSheet('Sheet1') and then checks getSheetId(sheetName); if HyperFormula did not register the sheet (undefined), the hook throws 'Failed to create sheet'. This indicates the HyperFormula engine rejected or failed to register the new sheet, usually due to an internal engine state problem or a misconfigured instance.

Source

Thrown at packages/desktop-client/src/hooks/useFormulaExecution.ts:105

}): FormulaCellValue {
  let hfInstance: ReturnType<typeof HyperFormula.buildEmpty> | null = null;

  try {
    hfInstance = HyperFormula.buildEmpty({
      licenseKey: 'gpl-v3',
      language: 'enUS',
      localeLang: typeof locale === 'string' ? locale : 'en-US',
      dateFormats: ['DD/MM/YYYY', 'YYYY-MM-DD', 'YYYY/MM/DD'],
      context: {
        formulaQuery: formulaQueryContext,
      },
    });

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

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

    if (namedExpressions) {
      for (const [name, value] of Object.entries(namedExpressions)) {
        hfInstance.addNamedExpression(
          name,
          typeof value === 'number' ? value : String(value),
        );
      }
    }

    hfInstance.setCellContents({ sheet: sheetId, col: 0, row: 0 }, [[formula]]);

    const cellValue = hfInstance.getCellValue({
      sheet: sheetId,
      col: 0,
      row: 0,
    });

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Check that the HyperFormula instance is created successfully and not destroyed before addSheet is called
  2. Verify the HyperFormula version supports addSheet/getSheetId as used, and pin/upgrade the dependency
  3. Add logging or a try/catch around hfInstance creation to surface the underlying engine error
  4. Report or guard: treat sheetId === undefined as a fallback by recreating the engine instance and retrying once

Example fix

// before
const hfInstance = createHyperFormula();
const sheetName = hfInstance.addSheet('Sheet1');
const sheetId = hfInstance.getSheetId(sheetName);
// after
let hfInstance;
try {
  hfInstance = createHyperFormula();
} catch (err) {
  throw new Error(`HyperFormula init failed: ${err.message}`);
}
const sheetName = hfInstance.addSheet('Sheet1');
const sheetId = hfInstance.getSheetId(sheetName);
if (sheetId === undefined) {
  throw new Error(`Failed to create sheet: sheetName=${sheetName}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

let hf;
try {
  hf = createHyperFormula();
  if (typeof hf.addSheet !== 'function') throw new Error('HyperFormula API unavailable');
} catch (err) {
  throw new Error(`HyperFormula unavailable: ${err.message}`);
}

Type guard

const isHyperFormulaInstance = (x: unknown): x is HyperFormula =>
  !!x && typeof (x as HyperFormula).addSheet === 'function' && typeof (x as HyperFormula).getSheetId === 'function';

Try / catch

try {
  const value = await executeFormula(formula);
} catch (err) {
  if (err.message === 'Failed to create sheet') {
    // recreate engine or fall back to non-formula path
  } else throw err;
}

Prevention

When it happens

Trigger: Calling executeFormula/evaluateFormulaWithContext when the HyperFormula instance is in an invalid or protected state, when addSheet returns undefined due to engine build failures, or when a duplicate/invalid configuration causes sheet registration to fail.

Common situations: Passing malformed options to createHyperFormula; running in an environment where HyperFormula fails to initialize (e.g. missing polyfills); engine instance reuse bugs after destroy; HyperFormula version behavior changes around addSheet.

Related errors


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