nwjs/nw.js · error · TypeError
'click' must be a valid Function
Error message
'click' must be a valid Function
What it means
When the `click` property is present on a normal/checkbox MenuItem option, the constructor requires it to be a function (typeof === 'function'). Anything else — a string, an async non-function, or an object — throws a TypeError. The callback is later invoked with no arguments from handleEvent when a 'click' event arrives.
Source
Thrown at src/api/menuitem/menuitem.js:71
if (option.hasOwnProperty('tooltip'))
option.tooltip = String(option.tooltip);
if (option.hasOwnProperty('enabled'))
option.enabled = Boolean(option.enabled);
if (option.hasOwnProperty('submenu')) {
if (v8_util.getConstructorName(option.submenu) != 'Menu')
throw new TypeError("'submenu' must be a valid Menu");
// Transfer only object id
v8_util.setHiddenValue(this, 'submenu', option.submenu);
option.submenu = option.submenu.id;
}
if (option.hasOwnProperty('click')) {
if (typeof option.click != 'function')
throw new TypeError("'click' must be a valid Function");
else
this.click = option.click;
}
} else if (option.type == 'separator') {
option = {
type: 'separator'
};
}
v8_util.setHiddenValue(this, 'option', option);
nw.allocateObject(this, option);
// All properties must be set after initialization.
if (!option.hasOwnProperty('icon'))
option.shadowIcon = '';
if (!option.hasOwnProperty('tooltip'))
option.tooltip = '';
if (!option.hasOwnProperty('enabled'))View on GitHub (pinned to e15da848e9)
Solutions
- Pass the actual function reference: `new nw.MenuItem({ label:'x', click: onOpen })`.
- If you have a method name string, resolve it first: `click: obj[methodName].bind(obj)`.
- Avoid deep-cloning the options object after attaching the callback.
Example fix
// before
new nw.MenuItem({ label: 'Open', click: 'onOpen' }); // throws
// after
new nw.MenuItem({ label: 'Open', click: onOpen }); Defensive patterns
Strategy: type-guard
Validate before calling
function buildItem(opt) {
if (opt.hasOwnProperty('click') && typeof opt.click !== 'function')
throw new TypeError('click must be a function');
return new nw.MenuItem(opt);
} Type guard
function isFunction(v) { return typeof v === 'function'; } Try / catch
try { return new nw.MenuItem(opt); }
catch (e) {
if (e instanceof TypeError && /click.*Function/.test(e.message)) {
if (typeof opt.click === 'string' && typeof window[opt.click] === 'function')
opt.click = window[opt.click];
else delete opt.click;
return new nw.MenuItem(opt);
} throw e;
} Prevention
- Pass function references, not method-name strings.
- Bind methods before assigning: `click: obj.handler.bind(obj)`.
- Do not clone/serialize options after attaching callbacks.
When it happens
Trigger: Calling new nw.MenuItem({ label:'x', click: 'onOpen' }) (string name instead of reference), { click: { handleEvent: fn } } (object), or { click: 42 }.
Common situations: Passing a method name as a string (a pattern from other frameworks). Stripping the function during serialization/cloning of options. Async transforms that lose the function type.
Related errors
- Menu.append() requires a valid MenuItem
- Invalid option.
- Invalid MenuItem type: {option.type}
- A normal MenuItem must have a label
- 'submenu' must be a valid Menu
AI-assisted analysis of nwjs/nw.js@e15da848e9 (2026-08-13).
Data as JSON: /api/errors/60275df752ff7de8.
Report an issue: GitHub.