actualbudget/actual · error

Unrecognized menu option: ${String(name)}

Error message

Unrecognized menu option: ${String(name)}

What it means

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.

Source

Thrown at packages/desktop-client/src/components/modals/AccountMenuModal.tsx:310

                  },
            ]}
            onMenuSelect={name => {
              setMenuOpen(false);
              switch (name) {
                case 'close':
                  onClose?.(account.id);
                  break;
                case 'reopen':
                  onReopen?.(account.id);
                  break;
                case 'balance':
                  onToggleRunningBalance?.();
                  break;
                case 'toggle-reconciled':
                  onToggleReconciled?.();
                  break;
                default:
                  throw new Error(`Unrecognized menu option: ${String(name)}`);
              }
            }}
          />
        </Popover>
      </Button>
    </View>
  );
}

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Add a `case` for the reported name in the onSelect switch, wired to the appropriate callback.
  2. Fix typos so the menu item's `name` matches a handled case exactly (kebab-case, case-sensitive).
  3. If the item is conditionally relevant, guard the case's callback with an optional-call like the others.
  4. Consider refactoring to a lookup map that logs unknown names instead of throwing in production.

Example fix

// before
case 'toggle-reconciled':
  onToggleReconciled?.();
  break;
default:
  throw new Error(`Unrecognized menu option: ${String(name)}`);
// after
case 'toggle-reconciled':
  onToggleReconciled?.();
  break;
case 'export':
  onExport?.();
  break;
default:
  console.warn('Unrecognized menu option:', name);
Defensive patterns

Strategy: type-guard

Validate before calling

const HANDLED = new Set(['toggle-running-balance', 'toggle-reconciled']);
if (!HANDLED.has(name)) {
  console.warn('Skipping unhandled menu option:', name);
  return;
}

Type guard

type AccountMenuOption = 'toggle-running-balance' | 'toggle-reconciled';
function isAccountMenuOption(name: string): name is AccountMenuOption {
  return ['toggle-running-balance', 'toggle-reconciled'].includes(name);
}

Try / catch

try {
  onSelect(name);
} catch (err) {
  if (String(err).includes('Unrecognized menu option')) {
    console.warn('Ignoring unknown menu option', name);
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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