{"record":{"id":"4f12e67f0ec93814","repo":"actualbudget/actual","slug":"unknown-format-type-type","errorCode":null,"errorMessage":"Unknown format type: ${type}","messagePattern":"Unknown format type: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/desktop-client/src/hooks/useFormat.ts","lineNumber":106,"sourceCode":"      }\n\n      if (typeof localValue !== 'number') {\n        throw new Error(\n          'Value is not a number (' + typeof localValue + '): ' + localValue,\n        );\n      }\n\n      return {\n        numericValue: localValue,\n        formattedString: integerToCurrency(\n          localValue,\n          formatter,\n          decimalPlaces,\n        ),\n      };\n    }\n    default:\n      throw new Error('Unknown format type: ' + type);\n  }\n}\n\nexport function useFormat(): UseFormatResult {\n  const [numberFormatPref] = useSyncedPref('numberFormat');\n  const [hideFractionPref] = useSyncedPref('hideFraction');\n  const [defaultCurrencyCodePref] = useSyncedPref('defaultCurrencyCode');\n  const [symbolPositionPref] = useSyncedPref('currencySymbolPosition');\n  const [spaceEnabledPref] = useSyncedPref(\n    'currencySpaceBetweenAmountAndSymbol',\n  );\n\n  const activeCurrency = useMemo(() => {\n    return getCurrency(defaultCurrencyCodePref || '');\n  }, [defaultCurrencyCodePref]);\n\n  const numberFormatConfig = useMemo(\n    () =>","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/desktop-client/src/hooks/useFormat.ts#L88-L124","documentation":"format() switches only over the documented FormatType union ('string', 'number', 'percentage', 'financial', 'financial-with-sign', 'financial-no-decimals'). Any other type value reaches the default branch and throws 'Unknown format type: <type>'. It protects against typos and stale string literals passed as the format type.","triggerScenarios":"Calling format(v, 'currency') or format(v, 'int') — names from other libraries or older Actual versions; a typo like 'financail'; a string from config/props typed as any where a FormatType is expected.","commonSituations":"Copy-pasting formatter calls from other codebases; migrating from an older API that used different type names; reading the format type from user-editable config without whitelisting.","solutions":["Use only the FormatType union values: string, number, percentage, financial, financial-with-sign, financial-no-decimals","Import and use the FormatType type so TypeScript rejects invalid literals at compile time (avoid typing the arg as string/any)","If you need a new type, extend the FormatType union and the switch in useFormat.ts rather than passing a custom string","Map legacy type names to current ones at the boundary before calling"],"exampleFix":"// before\nformat(value, 'currency'); // not a FormatType\n// after\nimport type { FormatType } from './useFormat';\nconst type: FormatType = 'financial';\nformat(value, type);","handlingStrategy":"type-guard","validationCode":"const FORMAT_TYPES = ['string','number','percentage','financial','financial-with-sign','financial-no-decimals'] as const;\nif (!FORMAT_TYPES.includes(type as FormatType)) throw new Error(`Unknown format type: ${type}`);","typeGuard":"function isFormatType(v: unknown): v is FormatType {\n  return typeof v === 'string' && ['string','number','percentage','financial','financial-with-sign','financial-no-decimals'].includes(v);\n}","tryCatchPattern":"let out: string;\ntry {\n  out = format(value, type);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Unknown format type')) {\n    console.warn(`Unknown format type ${type}, defaulting to string`);\n    out = format(value, 'string');\n  } else throw e;\n}","preventionTips":["Always annotate the type argument as FormatType so invalid literals fail at compile time","Whitelist format types read from user config with isFormatType before use","Map legacy/foreign format names to FormatType at integration boundaries","When adding a format type, update the union, the switch, and this guard together"],"tags":["formatting","typescript","switch-default"],"backgroundTag":"unsupported-enum-value","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}