{"record":{"id":"08d1e40adc14a0c9","repo":"nwjs/nw.js","slug":"listener-must-be-a-function-08d1e4","errorCode":null,"errorMessage":"listener must be a function","messagePattern":"listener must be a function","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/resources/api_nw_newwin.js","lineNumber":134,"sourceCode":"NWWindow.prototype.LoadingStateChanged = bindingUtil.createCustomEvent(\"nw.Window.LoadingStateChanged\", false, false);\nNWWindow.prototype.onDocumentStart     = bindingUtil.createCustomEvent(\"nw.Window.onDocumentStart\",     false, false);\nNWWindow.prototype.onDocumentEnd       = bindingUtil.createCustomEvent(\"nw.Window.onDocumentEnd\",       false, false);\nNWWindow.prototype.onZoom              = bindingUtil.createCustomEvent(\"nw.Window.onZoom\",              false, false);\nNWWindow.prototype.onClose             = bindingUtil.createCustomEvent(\"nw.Window.onClose\", true, false);\nNWWindow.prototype.onMinimized         = bindingUtil.createCustomEvent(\"nw.Window.onMinimized\", false, false);\nNWWindow.prototype.onMaximized         = bindingUtil.createCustomEvent(\"nw.Window.onMaximized\", false, false);\nNWWindow.prototype.onFullscreen        = bindingUtil.createCustomEvent(\"nw.Window.onFullscreen\", false, false);\nNWWindow.prototype.onResized           = bindingUtil.createCustomEvent(\"nw.Window.onResized\", false, false);\nNWWindow.prototype.onRestore           = bindingUtil.createCustomEvent(\"nw.Window.onRestore\", false, false);\n\nNWWindow.prototype.close = function (force) {\n  //console.log(`---> NWWindow.close: ${force} ${this.cWindow.id}`);\n  currentNWWindowInternal.close(force, this.cWindow.id);\n}\n\nNWWindow.prototype.once = function (event, listener, record) {\n  if (typeof listener !== 'function')\n    throw new TypeError('listener must be a function');\n  var fired = false;\n  var self = this;\n\n  function g() {\n    self.removeListener(event, g);\n    if (!fired) {\n      fired = true;\n      listener.apply(self, arguments);\n    }\n  }\n  this.on(event, g, false);\n  return this;\n};\n\nNWWindow.prototype.on = function (event, callback, record) {\n  var self = this;\n\n  // Wrap callback to bind to `self`.","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/nwjs/nw.js/blob/e15da848e9e08e6e467532dae78995c6ad2f55ee/src/resources/api_nw_newwin.js#L116-L152","documentation":"Thrown by NWWindow.prototype.once when the listener argument is not a function. `once` is a custom one-shot wrapper around on()/removeListener() defined directly on NWWindow, so it validates the listener itself before registering.","triggerScenarios":"Calling `win.once('closed', undefined)`, `win.once('maximized', 'handler')`, or passing a null reference.","commonSituations":"Handler looked up dynamically resolved to undefined; passing a config value instead of a function.","solutions":["Pass a function: `win.once('closed', () => {})`.","Guard: `if (typeof cb === 'function') win.once(ev, cb);`.","Prefer win.on() if you actually want repeated notifications."],"exampleFix":"// before\nwin.once('closed', handlers.onClose);\n// after\nif (typeof handlers.onClose === 'function') win.once('closed', handlers.onClose);","handlingStrategy":"type-guard","validationCode":"if (typeof listener !== 'function') throw new TypeError('listener must be a function');","typeGuard":"function isListener(v) { return typeof v === 'function'; }","tryCatchPattern":"try { win.once(ev, cb); } catch (e) { if (/listener/.test(e.message)) console.warn('non-function listener skipped'); else throw e; }","preventionTips":["Resolve handler references before subscribing.","Use win.on() for repeated notifications."],"tags":["window","events","type-check","nwjs"],"backgroundTag":null,"analyzedSha":"e15da848e9e08e6e467532dae78995c6ad2f55ee","analyzedAt":"2026-08-13T04:15:35.452Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}