actualbudget/actual · error
Unrecognized menu option: ${String(name)}
Error message
Unrecognized menu option: ${String(name)} What it means
EnvelopeIncomeBalanceMenuModal throws when the category/envelope menu's onSelect receives an option name with no case in its switch. Handled options include carryover and view; anything else is an invariant violation indicating a menu item was rendered without a corresponding handler.
Source
Thrown at packages/desktop-client/src/components/modals/EnvelopeIncomeBalanceMenuModal.tsx:120
textAlign: 'center',
...styles.veryLargeText,
}}
/>
)}
</BalanceWithCarryover>
</View>
<Menu
getItemStyle={() => defaultMenuItemStyle}
onMenuSelect={name => {
switch (name) {
case 'carryover':
onCarryover?.(!carryover);
break;
case 'view':
onShowActivity?.();
break;
default:
throw new Error(`Unrecognized menu option: ${String(name)}`);
}
}}
items={[
{
name: 'carryover',
text: carryover
? t('Disable auto hold')
: t('Enable auto hold'),
},
{
name: 'view',
text: t('View transactions'),
},
]}
/>
</>
)}
</Modal>View on GitHub (pinned to d4334cb6e6)
Solutions
- Add a case for the reported name with the appropriate callback call.
- Ensure every object in the `items` array has a matching case in the switch (name strings must match exactly).
- Swap the throw for console.warn if unknown options should be ignored at runtime.
- Derive the union of item names as a type and make the switch exhaustive to catch this at compile time.
Example fix
// before
case 'view':
onShowActivity?.();
break;
default:
throw new Error(`Unrecognized menu option: ${String(name)}`);
// after
case 'view':
onShowActivity?.();
break;
case 'transfer':
onTransfer?.();
break;
default:
console.warn('Unrecognized menu option:', name); Defensive patterns
Strategy: type-guard
Validate before calling
const HANDLED = new Set(['carryover', 'view']);
if (!HANDLED.has(name)) {
console.warn('Unknown envelope menu option:', name);
return;
} Type guard
type EnvelopeMenuOption = 'carryover' | 'view';
function isEnvelopeMenuOption(name: string): name is EnvelopeMenuOption {
return ['carryover', 'view'].includes(name);
} Try / catch
try {
onSelect(name);
} catch (err) {
if (String(err).includes('Unrecognized menu option')) {
console.warn('Ignoring menu option', name);
} else {
throw err;
}
} Prevention
- Define item names as a literal union shared between the items array and the switch.
- Add a unit test asserting every items entry has a switch case.
- Replace the throw with a warn-level default branch for runtime resilience.
When it happens
Trigger: Selecting an item in the envelope/income-balance context menu whose `name` isn't handled — typically after a new item is appended to the modal's `items` array (e.g. 'transfer', 'hide') without adding its case.
Common situations: Contributors adding an envelope menu action without extending the switch; renames of an existing item name string; forks injecting extra menu entries.
Related errors
- Unrecognized menu option: ${String(name)}
- Unrecognized menu item: ${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/7187d0aaeeccfc2d.
Report an issue: GitHub.