actualbudget/actual · error
Unrecognized menu option: ${name}
Error message
Unrecognized menu option: ${name} What it means
ScheduledTransactionMenu throws when a scheduled-transaction menu option has no case in its onSelect switch. Known cases include post, post-today, skip, and complete; the default branch treats any other name as an internal bug and throws.
Source
Thrown at packages/desktop-client/src/components/modals/ScheduledTransactionMenuModal.tsx:143
return (
<Menu
{...props}
onMenuSelect={name => {
switch (name) {
case 'post':
onPost?.(transactionId);
break;
case 'post-today':
onPost?.(transactionId, true);
break;
case 'skip':
onSkip?.(transactionId);
break;
case 'complete':
onComplete?.(transactionId);
break;
default:
throw new Error(`Unrecognized menu option: ${name}`);
}
}}
items={[
{ name: 'post', text: t('Post transaction') },
{ name: 'post-today', text: t('Post transaction today') },
...(canBeSkipped
? [{ name: 'skip', text: t('Skip next scheduled date') }]
: []),
...(canBeCompleted
? [{ name: 'complete', text: t('Mark as completed') }]
: []),
]}
/>
);
}
View on GitHub (pinned to d4334cb6e6)
Solutions
- Add the missing case to the onSelect switch in ScheduledTransactionMenu.
- Cross-check each entry in the items array against the switch cases; fix any string mismatches.
- Log and ignore unknown options instead of throwing if graceful degradation is preferred.
- Type items' names as a closed union shared by both the items array and the switch.
Example fix
// before
case 'complete':
onComplete?.(transactionId);
break;
default:
throw new Error(`Unrecognized menu option: ${name}`);
// after
case 'complete':
onComplete?.(transactionId);
break;
case 'edit':
onEdit?.(transactionId);
break;
default:
console.warn('Unrecognized menu option:', name); Defensive patterns
Strategy: type-guard
Validate before calling
const HANDLED = new Set(['post', 'post-today', 'skip', 'complete']);
if (!HANDLED.has(name)) {
console.warn('Unknown schedule menu option:', name);
return;
} Type guard
type ScheduleMenuOption = 'post' | 'post-today' | 'skip' | 'complete';
function isScheduleMenuOption(name: string): name is ScheduleMenuOption {
return ['post', 'post-today', 'skip', 'complete'].includes(name);
} Try / catch
try {
onSelect(name);
} catch (err) {
if (String(err).includes('Unrecognized menu option')) {
console.warn('Unhandled schedule option', name);
} else {
throw err;
}
} Prevention
- Keep a single source of truth (union type) for schedule menu option names.
- When adding an item to the items array, add the case in the same commit.
- Cover all schedule menu options in component tests.
When it happens
Trigger: Choosing a menu item for a scheduled transaction whose `name` isn't in the switch — e.g. after adding a new option to the `items` array (like 'edit' or 'delete') without a corresponding case.
Common situations: New menu items added in a feature branch without updating onSelect; a typo in a name string between items and cases; forks/patches extending the schedule menu.
Related errors
- Unrecognized menu option: ${String(name)}
- Unrecognized menu item: ${name}
- Unrecognized menu option: ${String(name)}
- Unrecognized menu option: ${String(item)}
- Unrecognized menu item: ${name}
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/fd56611337ab62ec.
Report an issue: GitHub.