actualbudget/actual · error

Unrecognized menu item: ${name}

Error message

Unrecognized menu item: ${name}

What it means

BudgetPageMenuModal's onMenuSelect throws when the selected menu item's `name` has no case in its switch. The modal enumerates known budget-page actions (e.g. toggle hidden categories, switch budget file); any unrecognized name is treated as an internal invariant violation and thrown rather than silently ignored.

Source

Thrown at packages/desktop-client/src/components/modals/BudgetPageMenuModal.tsx:82

}: BudgetPageMenuProps) {
  const [showHiddenCategories] = useLocalPref('budget.showHiddenCategories');

  const onMenuSelect = (name: string) => {
    switch (name) {
      case 'add-category-group':
        onAddCategoryGroup?.();
        break;
      // case 'edit-mode':
      //   onEditMode?.(true);
      //   break;
      case 'toggle-hidden-categories':
        onToggleHiddenCategories?.();
        break;
      case 'switch-budget-file':
        onSwitchBudgetFile?.();
        break;
      default:
        throw new Error(`Unrecognized menu item: ${name}`);
    }
  };
  const { t } = useTranslation();

  return (
    <Menu
      {...props}
      onMenuSelect={onMenuSelect}
      items={[
        {
          name: 'add-category-group',
          text: t('Add category group'),
        },
        {
          name: 'toggle-hidden-categories',
          text: `${!showHiddenCategories ? t('Show hidden categories') : t('Hide hidden categories')}`,
        },
        {

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Add the missing `case '<name>'` to onMenuSelect with the matching callback.
  2. Verify each entry in the menu's `items` array has a corresponding case; align name strings exactly.
  3. Replace the throw with a console.warn + early return if you want unknown items ignored in production.
  4. Type the item names as a union so TypeScript forces the switch to stay exhaustive.

Example fix

// before
case 'switch-budget-file':
  onSwitchBudgetFile?.();
  break;
default:
  throw new Error(`Unrecognized menu item: ${name}`);
// after
case 'switch-budget-file':
  onSwitchBudgetFile?.();
  break;
case 'reset-cache':
  onResetCache?.();
  break;
default:
  console.warn('Unrecognized menu item:', name);
Defensive patterns

Strategy: type-guard

Validate before calling

const KNOWN = new Set(['toggle-hidden-categories', 'switch-budget-file'] /* all cases */);
if (!KNOWN.has(name)) {
  console.warn('Unknown budget menu item:', name);
  return;
}

Type guard

type BudgetMenuItem = 'toggle-hidden-categories' | 'switch-budget-file';
function isBudgetMenuItem(name: string): name is BudgetMenuItem {
  return ['toggle-hidden-categories', 'switch-budget-file'].includes(name);
}

Try / catch

try {
  onMenuSelect(name);
} catch (err) {
  if (String(err).includes('Unrecognized menu item')) {
    console.warn('Unhandled budget menu item', name);
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: User selects a budget page menu item whose `name` string is not one of the cases handled in onMenuSelect — usually after adding a new menu item (e.g. under 'tools' or 'customize') without extending the switch.

Common situations: Contributors adding a new budget menu action without updating onMenuSelect; a typo or rename of an existing item's name; a fork/patch that injects extra items into the items array.

Related errors


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