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
- Add the missing `case '<name>'` to onMenuSelect with the matching callback.
- Verify each entry in the menu's `items` array has a corresponding case; align name strings exactly.
- Replace the throw with a console.warn + early return if you want unknown items ignored in production.
- 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
- Derive the switch's case union from the same type used for items' names.
- Enable exhaustive-switch checking (satisfies never in default) to catch gaps at compile time.
- Add an E2E test iterating all rendered budget menu items.
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
- Unrecognized menu option: ${String(name)}
- Unrecognized menu option: ${String(name)}
- Unrecognized menu option: ${String(item)}
- Unhandled edit field name: ${String(name)}
- Unrecognized menu option: ${name}
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/5085745485513157.
Report an issue: GitHub.