{"record":{"id":"87caacfa089de9c7","repo":"nwjs/nw.js","slug":"menu-property-requries-a-valid-menu-87caac","errorCode":null,"errorMessage":"'menu' property requries a valid Menu","messagePattern":"'menu' property requries a valid Menu","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/resources/api_nw_tray.js","lineNumber":150,"sourceCode":"Tray.prototype.__defineSetter__('iconsAreTemplates', function(val) {\n  this.handleSetter('iconsAreTemplates', 'SetIconsAreTemplates', Boolean, val);\n});\n\nTray.prototype.__defineGetter__('tooltip', function() {\n  return this.handleGetter('tooltip');\n});\n\nTray.prototype.__defineSetter__('tooltip', function(val) {\n  this.handleSetter('tooltip', 'SetTooltip', String, val);\n});\n\nTray.prototype.__defineGetter__('menu', function() {\n  return privates(this).menu;\n});\n\nTray.prototype.__defineSetter__('menu', function(val) {\n  if (val.constructor.name != 'Menu')\n    throw new TypeError(\"'menu' property requries a valid Menu\");\n\n  privates(this).menu = val;\n  nw.Obj.callObjectMethod(this.id, 'Tray', 'SetMenu', [ val.id ]);\n});\n\nTray.prototype.remove = function() {\n  nw.Obj.callObjectMethod(this.id, 'Tray', 'Remove', []);\n  delete trayEvents.objs[this.id];\n}\n\nexports.binding = Tray;\n\n","sourceCodeStart":132,"sourceCodeEnd":163,"githubUrl":"https://github.com/nwjs/nw.js/blob/e15da848e9e08e6e467532dae78995c6ad2f55ee/src/resources/api_nw_tray.js#L132-L163","documentation":"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').","triggerScenarios":"tray.menu = [{ label: 'x' }] (array); tray.menu = somePlainObject; tray.menu = aMenuBuiltInADifferentRealmWithMangledName.","commonSituations":"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.","solutions":["Assign a constructed nw.Menu: tray.menu = new nw.Menu({ type: 'menubar' }).","Preserve function names in your bundler config (keep_fnames: true) to keep constructor.name intact.","Build items with nw.MenuItem and append to the Menu before assigning."],"exampleFix":"// before\ntray.menu = [{ label: 'Quit' }];\n// after\nconst menu = new nw.Menu({ type: 'menubar' });\nmenu.append(new nw.MenuItem({ label: 'Quit' }));\ntray.menu = menu;","handlingStrategy":"type-guard","validationCode":"function setTrayMenu(tray, menu) {\n  if (!(menu instanceof nw.Menu)) {\n    throw new TypeError('tray.menu requires an nw.Menu instance');\n  }\n  tray.menu = menu;\n}","typeGuard":"function isMenuInstance(o) { return o && o.constructor && o.constructor.name === 'Menu'; }","tryCatchPattern":null,"preventionTips":["Assign only constructed nw.Menu instances to tray.menu.","Rebuild the menu with nw.MenuItem entries before assignment.","Keep bundler keep_fnames on to preserve constructor.name."],"tags":["nwjs","tray","validation","menu","setter","constructor-name"],"backgroundTag":null,"analyzedSha":"e15da848e9e08e6e467532dae78995c6ad2f55ee","analyzedAt":"2026-08-13T04:15:35.452Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}