{"record":{"id":"ed81e27a48b01cdc","repo":"actualbudget/actual","slug":"unrecognized-menu-option-string-name-ed81e2","errorCode":null,"errorMessage":"Unrecognized menu option: ${String(name)}","messagePattern":"Unrecognized menu option: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/desktop-client/src/components/modals/AccountMenuModal.tsx","lineNumber":310,"sourceCode":"                  },\n            ]}\n            onMenuSelect={name => {\n              setMenuOpen(false);\n              switch (name) {\n                case 'close':\n                  onClose?.(account.id);\n                  break;\n                case 'reopen':\n                  onReopen?.(account.id);\n                  break;\n                case 'balance':\n                  onToggleRunningBalance?.();\n                  break;\n                case 'toggle-reconciled':\n                  onToggleReconciled?.();\n                  break;\n                default:\n                  throw new Error(`Unrecognized menu option: ${String(name)}`);\n              }\n            }}\n          />\n        </Popover>\n      </Button>\n    </View>\n  );\n}\n","sourceCodeStart":292,"sourceCodeEnd":319,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/desktop-client/src/components/modals/AccountMenuModal.tsx#L292-L319","documentation":"AccountMenuModal's switch over menu item names throws in the `default` branch when `onSelect` receives a name it doesn't recognize. Every menu item rendered by this modal must have a corresponding case in the handler; this invariant catches new/renamed items that were added to the menu without updating the handler.","triggerScenarios":"The `Menu` inside AdditionalAccountMenu invokes `onSelect` with a `name` string not in the handled cases (e.g. 'toggle-running-balance', 'toggle-reconciled', and whatever else) — typically after a code change adds a menu item without adding its case.","commonSituations":"Developers adding a new account menu action and forgetting the switch case; plugins/patches or forks injecting extra menu items; typos between the item's `name` prop and the case string.","solutions":["Add a `case` for the reported name in the onSelect switch, wired to the appropriate callback.","Fix typos so the menu item's `name` matches a handled case exactly (kebab-case, case-sensitive).","If the item is conditionally relevant, guard the case's callback with an optional-call like the others.","Consider refactoring to a lookup map that logs unknown names instead of throwing in production."],"exampleFix":"// before\ncase 'toggle-reconciled':\n  onToggleReconciled?.();\n  break;\ndefault:\n  throw new Error(`Unrecognized menu option: ${String(name)}`);\n// after\ncase 'toggle-reconciled':\n  onToggleReconciled?.();\n  break;\ncase 'export':\n  onExport?.();\n  break;\ndefault:\n  console.warn('Unrecognized menu option:', name);","handlingStrategy":"type-guard","validationCode":"const HANDLED = new Set(['toggle-running-balance', 'toggle-reconciled']);\nif (!HANDLED.has(name)) {\n  console.warn('Skipping unhandled menu option:', name);\n  return;\n}","typeGuard":"type AccountMenuOption = 'toggle-running-balance' | 'toggle-reconciled';\nfunction isAccountMenuOption(name: string): name is AccountMenuOption {\n  return ['toggle-running-balance', 'toggle-reconciled'].includes(name);\n}","tryCatchPattern":"try {\n  onSelect(name);\n} catch (err) {\n  if (String(err).includes('Unrecognized menu option')) {\n    console.warn('Ignoring unknown menu option', name);\n  } else {\n    throw err;\n  }\n}","preventionTips":["Keep the items array and the onSelect switch in the same file, adjacent to each other.","Type menu item names as a string-literal union so an added item without a case fails typecheck.","Write a test that clicks every menu item the modal renders."],"tags":["react","menu","switch-statement","developer-error"],"backgroundTag":"unhandled-switch-case","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}