{"record":{"id":"1d6908f8235f7303","repo":"nwjs/nw.js","slug":"must-set-title-or-icon-field-in-option-1d6908","errorCode":null,"errorMessage":"Must set 'title' or 'icon' field in option","messagePattern":"Must set 'title' or 'icon' field in option","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/resources/api_nw_tray.js","lineNumber":29,"sourceCode":"  var tray = trayEvents.objs[id];\n  if (!tray)\n    return;\n  var args = Array.prototype.slice.call(arguments, 1);\n  args.unshift('click');\n  tray.emit.apply(tray, args);\n});\n\nfunction Tray(option) {\n  if (!(this instanceof Tray)) {\n    return new Tray(option);\n  }\n  EventEmitter.apply(this);\n\n  if (typeof option != 'object')\n    throw new TypeError('Invalid option.');\n\n  if (!option.hasOwnProperty('title') && !option.hasOwnProperty('icon'))\n    throw new TypeError(\"Must set 'title' or 'icon' field in option\");\n\n  if (!option.hasOwnProperty('title'))\n    option.title = '';\n  else\n    option.title = String(option.title);\n\n  if (option.hasOwnProperty('icon')) {\n    option.shadowIcon = String(option.icon);\n    option.icon = nwNative.getAbsolutePath(option.icon);\n  }\n\n  if (option.hasOwnProperty('alticon')) {\n    option.shadowAlticon = String(option.alticon);\n    option.alticon = nwNative.getAbsolutePath(option.alticon);\n  }\n\n  if (option.hasOwnProperty('iconsAreTemplates'))\n    option.iconsAreTemplates = Boolean(option.iconsAreTemplates);","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/nwjs/nw.js/blob/e15da848e9e08e6e467532dae78995c6ad2f55ee/src/resources/api_nw_tray.js#L11-L47","documentation":"Thrown by the Tray constructor when option is an object but has neither a 'title' nor an 'icon' property. At least one of these must be present because the native Tray requires something to display (text or image). Both are checked via hasOwnProperty, so inherited properties do not count.","triggerScenarios":"new nw.Tray({ tooltip: 'x' }) (only tooltip); new nw.Tray({}) (empty object); new nw.Tray({ click: fn }) (only a click handler).","commonSituations":"Building the options object from optional config where both title and icon ended up unset; intending to set the icon later via the setter but the constructor still requires one upfront; spreading a partial config.","solutions":["Include at least one of title or icon in the initial options: { title: '' } is acceptable (empty title) if you plan to set an icon immediately after.","Default to a title or icon path in your config loader before constructing the Tray."],"exampleFix":"// before\nnew nw.Tray({ tooltip: 'My App', click: handler });\n// after\nnew nw.Tray({ title: 'My App', tooltip: 'My App', click: handler });","handlingStrategy":"validation","validationCode":"if (!option || (!('title' in option) && !('icon' in option))) {\n  throw new TypeError(\"Tray option must include 'title' or 'icon'\");\n}","typeGuard":"function hasTrayTitleOrIcon(o) { return !!o && (o.hasOwnProperty('title') || o.hasOwnProperty('icon')); }","tryCatchPattern":null,"preventionTips":["Always supply at least a title or an icon path.","Default to an empty title (title: '') if you plan to set an icon immediately after.","Validate optional config builders so at least one display field survives."],"tags":["nwjs","tray","validation","required-field"],"backgroundTag":null,"analyzedSha":"e15da848e9e08e6e467532dae78995c6ad2f55ee","analyzedAt":"2026-08-13T04:15:35.452Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}