nocobase/nocobase · error · Error
Plugin settings menuKey does not exist: menuKey=${options.me
Error message
Plugin settings menuKey does not exist: menuKey=${options.menuKey} What it means
PluginSettingsManager.addPageTabItem() registers a tab item under an existing settings menu. Before registering, it requires this.menus[options.menuKey] to exist; if the menuKey was never registered (or was registered with a different key), it throws this error. This prevents attaching tab items to a nonexistent menu whose page routing could not be resolved.
Source
Thrown at packages/core/client-v2/src/PluginSettingsManager.ts:206
this.menus[menuName] = nextMenu;
this.syncMenuRoute(nextMenu);
this.clearCache();
}
/**
* 注册或更新 page item。
*
* @param {PluginSettingsPageItemOptions} options page 配置
* @returns {void}
* @throws {Error} 当 menu 不存在或路径冲突时抛错
*/
addPageTabItem(options: PluginSettingsPageItemOptions) {
this.assertMenuKey(options.menuKey, 'menuKey');
const menu = this.menus[options.menuKey];
if (!menu) {
throw new Error(`Plugin settings menuKey does not exist: menuKey=${options.menuKey}`);
}
const pageName = this.getPageName(options.menuKey, options.key);
const nextPage: InternalPageItemRecord = {
...this.pages[pageName],
...options,
menuKey: options.menuKey,
key: options.key,
name: pageName,
};
this.assertIndexConflict(nextPage);
this.assertPathConflict(pageName, this.getRoutePath(pageName));
this.pages[pageName] = nextPage;
this.syncPageRoute(nextPage);
this.clearCache();
}View on GitHub (pinned to fa42722fef)
Solutions
- Ensure the menu is registered first: call registerMenu (or equivalent) with the same menuKey before addPageTabItem
- Log/inspect available keys (Object.keys(menus)) and fix typos in options.menuKey
- Check plugin load order/dependencies so the menu-owning plugin initializes first
- If upgrading, update the menuKey to the new name from the owning plugin's changelog
Example fix
// before
pluginSettingsManager.addPageTabItem({ menuKey: 'ai-settings-typo', key: 'model', title: 'Model' });
// after
pluginSettingsManager.registerMenu({ name: 'ai-settings', title: 'AI Settings' });
pluginSettingsManager.addPageTabItem({ menuKey: 'ai-settings', key: 'model', title: 'Model' }); Defensive patterns
Strategy: validation
Validate before calling
if (!pluginSettingsManager.menus[menuKey]) {
throw new Error(`Register menu "${menuKey}" before addPageTabItem`);
}
pluginSettingsManager.addPageTabItem({ menuKey, key, title }); Type guard
function menuExists(mgr: PluginSettingsManager, menuKey: string): boolean {
return menuKey in (mgr as unknown as { menus: Record<string, unknown> }).menus;
} Try / catch
try {
pluginSettingsManager.addPageTabItem({ menuKey, key: 'model', title: 'Model' });
} catch (err) {
if (String(err.message).startsWith('Plugin settings menuKey does not exist')) {
pluginSettingsManager.registerMenu({ name: menuKey, title: 'AI Settings' });
pluginSettingsManager.addPageTabItem({ menuKey, key: 'model', title: 'Model' });
} else throw err;
} Prevention
- Always registerMenu before addPageTabItem in the same plugin
- Extract menuKey strings into shared constants instead of inline literals
- Verify plugin load order so menu owners initialize before consumers
- After version upgrades, grep for old menu keys and update them to renamed values
When it happens
Trigger: Calling addPageTabItem({ menuKey: 'X', ... }) (e.g. from registerPluginAISettingsPages) before registerMenu/registerPage was called with menuKey 'X', or with a typo'd/stale key after the menu was renamed or removed.
Common situations: Plugin registration order issues where another plugin's settings page is added before the menu owner plugin initializes; menu key renamed in a version upgrade while consumer plugins still use the old key; copy-paste typos in menuKey strings.
Related errors
- ${attr} neither ${firstKey}'s association nor ${firstKey}'s
- Temporary file URL is missing
- [useCodeRunner] restore logger failed:
- console.warn()
- console.warn(
AI-assisted analysis of nocobase/nocobase@fa42722fef (2026-09-01).
Data as JSON: /api/errors/01c0d8d8d09a2905.
Report an issue: GitHub.