nwjs/nw.js · error · TypeError

'menu' property requries a valid Menu

Error message

'menu' property requries a valid Menu

What it means

Thrown by the Tray.prototype 'menu' setter (tray.menu = val) when val.constructor.name !== 'Menu'. Same shape check as the constructor's menu validation (error 54) but applied on reassignment after construction. The setter then reads val.id to call the native SetMenu, so a non-Menu object would crash downstream anyway. Note the message contains a typo ('requries').

Source

Thrown at src/resources/api_nw_tray.js:150

Tray.prototype.__defineSetter__('iconsAreTemplates', function(val) {
  this.handleSetter('iconsAreTemplates', 'SetIconsAreTemplates', Boolean, val);
});

Tray.prototype.__defineGetter__('tooltip', function() {
  return this.handleGetter('tooltip');
});

Tray.prototype.__defineSetter__('tooltip', function(val) {
  this.handleSetter('tooltip', 'SetTooltip', String, val);
});

Tray.prototype.__defineGetter__('menu', function() {
  return privates(this).menu;
});

Tray.prototype.__defineSetter__('menu', function(val) {
  if (val.constructor.name != 'Menu')
    throw new TypeError("'menu' property requries a valid Menu");

  privates(this).menu = val;
  nw.Obj.callObjectMethod(this.id, 'Tray', 'SetMenu', [ val.id ]);
});

Tray.prototype.remove = function() {
  nw.Obj.callObjectMethod(this.id, 'Tray', 'Remove', []);
  delete trayEvents.objs[this.id];
}

exports.binding = Tray;

View on GitHub (pinned to e15da848e9)

Solutions

  1. Assign a constructed nw.Menu: tray.menu = new nw.Menu({ type: 'menubar' }).
  2. Preserve function names in your bundler config (keep_fnames: true) to keep constructor.name intact.
  3. Build items with nw.MenuItem and append to the Menu before assigning.

Example fix

// before
tray.menu = [{ label: 'Quit' }];
// after
const menu = new nw.Menu({ type: 'menubar' });
menu.append(new nw.MenuItem({ label: 'Quit' }));
tray.menu = menu;
Defensive patterns

Strategy: type-guard

Validate before calling

function setTrayMenu(tray, menu) {
  if (!(menu instanceof nw.Menu)) {
    throw new TypeError('tray.menu requires an nw.Menu instance');
  }
  tray.menu = menu;
}

Type guard

function isMenuInstance(o) { return o && o.constructor && o.constructor.name === 'Menu'; }

Prevention

When it happens

Trigger: tray.menu = [{ label: 'x' }] (array); tray.menu = somePlainObject; tray.menu = aMenuBuiltInADifferentRealmWithMangledName.

Common situations: Updating the tray menu at runtime with a freshly built array of items instead of a constructed nw.Menu; minified builds where constructor.name is stripped; reassigning menu after the tray was created with only a title.

Related errors


AI-assisted analysis of nwjs/nw.js@e15da848e9 (2026-08-13). Data as JSON: /api/errors/87caacfa089de9c7. Report an issue: GitHub.