{"record":{"id":"01f27b29441d6624","repo":"actualbudget/actual","slug":"formula-error-cellvalue-type","errorCode":null,"errorMessage":"Formula error: ${cellValue.type}","messagePattern":"Formula error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/desktop-client/src/hooks/useFormulaExecution.ts","lineNumber":127,"sourceCode":"      for (const [name, value] of Object.entries(namedExpressions)) {\n        hfInstance.addNamedExpression(\n          name,\n          typeof value === 'number' ? value : String(value),\n        );\n      }\n    }\n\n    hfInstance.setCellContents({ sheet: sheetId, col: 0, row: 0 }, [[formula]]);\n\n    const cellValue = hfInstance.getCellValue({\n      sheet: sheetId,\n      col: 0,\n      row: 0,\n    });\n\n    if (isHyperFormulaError(cellValue)) {\n      if (throwOnCellError) {\n        throw new Error(`Formula error: ${cellValue.type}`);\n      }\n      return null;\n    }\n\n    return cellValue as FormulaCellValue;\n  } finally {\n    hfInstance?.destroy();\n  }\n}\n\nexport function useFormulaExecution(\n  formula: string,\n  queries: QueriesMap,\n  queriesVersion?: number,\n  namedExpressions?: Record<string, number | string>,\n  accounts?: SimpleAccount[],\n) {\n  const locale = useLocale();","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/desktop-client/src/hooks/useFormulaExecution.ts#L109-L145","documentation":"After evaluating a formula, the hook checks isHyperFormulaError(cellValue) and, when throwOnCellError is enabled, throws 'Formula error: <type>'. HyperFormula represents formula failures (e.g. #DIV/0!, #NAME?, #REF!) as error-typed cell values rather than exceptions, so this surfaces those cell-level errors as a JavaScript error.","triggerScenarios":"Evaluating a formula that produces a HyperFormula error value (DetailedErrorType such as DIV_BY_ZERO, NAME, REF, VALUE, CYCLE) while the caller set throwOnCellError to true.","commonSituations":"Typing a misspelled function name (#NAME?), dividing by zero or by an empty cell (#DIV/0!), referencing a deleted range (#REF!), or creating circular references in user-entered formulas.","solutions":["Fix the formula string to avoid the specific error type (validate function names and referenced cells)","Set throwOnCellError to false if a null result is acceptable for error-valued cells","Catch the error and inspect the type suffix to show a user-friendly message","Pre-validate the formula with HyperFormula's error-listing API before evaluating"],"exampleFix":"// before\nconst value = await executeFormula('=1/0', { throwOnCellError: true });\n// after\nlet value;\ntry {\n  value = await executeFormula('=IFERROR(1/0, 0)', { throwOnCellError: true });\n} catch (err) {\n  console.warn('Cell error:', err.message); // \"Formula error: DIV_BY_ZERO\"\n  value = null;\n}","handlingStrategy":"type-guard","validationCode":"const known = /^(SUM|IF|IFERROR|ROUND|DIVIDE)\\s*\\(/i;\nif (!known.test(formula.trim())) console.warn('Formula uses unfamiliar function:', formula);","typeGuard":"const isCellError = (v: CellValue): v is DetailedErrorCell =>\n  typeof v === 'object' && v !== null && 'type' in v && 'value' in v && (v as any).type !== undefined;\n// or reuse the hook's exported isHyperFormulaError(cellValue)","tryCatchPattern":"try {\n  const value = await executeFormula(formula, { throwOnCellError: true });\n} catch (err) {\n  const match = /^Formula error: (.+)$/.exec(err.message);\n  if (match) showFormulaErrorTooltip(match[1]); // e.g. DIV_BY_ZERO\n  else throw err;\n}","preventionTips":["Wrap risky divisions in IFERROR in user-entered formulas","Prefer throwOnCellError: false when null is an acceptable outcome","Validate function names against HyperFormula's supported list before evaluation","Check referenced cells/ranges exist before building the formula"],"tags":["hyperformula","formula","spreadsheet"],"backgroundTag":"formula-evaluation-error","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}