nwjs/nw.js · error · TypeError
Invalid menu type: {option.type}
Error message
Invalid menu type: {option.type} What it means
Menu's constructor accepts only two menu types: 'contextmenu' and 'menubar'. If option is not an object it defaults to {type:'contextmenu'}, but once an object is supplied its `type` must be one of those two literals or a TypeError is thrown. The invalid value is interpolated into the message.
Source
Thrown at src/api/menu/menu.js:30
// l copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
// OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
var v8_util = process.binding('v8_util');
var EventEmitter = process.EventEmitter;
function Menu(option) {
if (typeof option != 'object')
option = { type: 'contextmenu' };
if (option.type != 'contextmenu' && option.type != 'menubar')
throw new TypeError('Invalid menu type: ' + option.type);
this.type = option.type;
v8_util.setHiddenValue(this, 'items', []);
nw.allocateObject(this, option);
}
require('util').inherits(Menu, exports.Base);
Menu.prototype.__defineGetter__('items', function() {
return v8_util.getHiddenValue(this, 'items');
});
Menu.prototype.__defineSetter__('items', function(val) {
throw new Error('Menu.items is immutable');
});
Menu.prototype.append = function(menu_item) {
if (v8_util.getConstructorName(menu_item) != 'MenuItem')
throw new TypeError("Menu.append() requires a valid MenuItem");View on GitHub (pinned to e15da848e9)
Solutions
- Use { type: 'contextmenu' } or { type: 'menubar' }.
- Pass no argument (or null) to get the default contextmenu, rather than an empty object.
- Check for typos and underscores; the values are single lowercase words.
Example fix
// before
new nw.Menu({ type: 'popup' }); // throws
new nw.Menu({}); // also throws (type undefined)
// after
new nw.Menu({ type: 'contextmenu' });
new nw.Menu(); // defaults to contextmenu Defensive patterns
Strategy: validation
Validate before calling
var VALID = ['contextmenu', 'menubar'];
function buildMenu(option) {
if (option && option.type && VALID.indexOf(option.type) === -1)
throw new Error('Invalid menu type: ' + option.type);
return new nw.Menu(option);
} Type guard
function isMenuType(t) { return t === 'contextmenu' || t === 'menubar'; } Try / catch
try { return new nw.Menu(option); }
catch (e) {
if (e instanceof TypeError && /Invalid menu type/.test(e.message)) {
return new nw.Menu({ type: 'contextmenu' }); // default fallback
} throw e;
} Prevention
- Omit the argument entirely for a default contextmenu.
- Never pass an empty object expecting the default.
- Whitelist the type before construction.
When it happens
Trigger: Calling new nw.Menu({ type: 'popup' }), { type: 'bar' }, { type: 'menu' }, or any other string. Also { type: undefined } when the object exists but lacks a valid type.
Common situations: Developers coming from Electron (where Menu types are different) or guessing the type name ('popup', 'toolbar', 'tray'). Typos like 'context-menu' or 'menu_bar'. Passing an empty object when intending the default (an empty object does NOT default — its type is undefined and throws).
Related errors
- Invalid option.
- Invalid MenuItem type: {option.type}
- A normal MenuItem must have a label
- Invalid option.
- Shortcut requires 'key' to specify key combinations.
AI-assisted analysis of nwjs/nw.js@e15da848e9 (2026-08-13).
Data as JSON: /api/errors/c443d85d5d147706.
Report an issue: GitHub.