nwjs/nw.js · error · TypeError

listener must be a function

Error message

listener must be a function

What it means

Thrown by nw.App.once when the listener argument is not a function. `once` is a custom EventEmitter-style method that registers a one-shot listener on the compiled API object, bypassing the API bridge, so it performs its own typeof check before registering.

Source

Thrown at src/resources/api_nw_app.js:78

  });
  apiFunctions.setHandleRequest('getProxyForURL', function() {
    return nwNatives.getProxyForURL.apply(this, arguments);
  });
  apiFunctions.setHandleRequest('addOriginAccessWhitelistEntry', function() {
    nwNatives.addOriginAccessWhitelistEntry.apply(this, arguments);
  });
  apiFunctions.setHandleRequest('removeOriginAccessWhitelistEntry', function() {
    nwNatives.removeOriginAccessWhitelistEntry.apply(this, arguments);
  });

  // Event methods defined directly on compiledApi to bypass the API bridge's
  // argument parsing which wraps function callbacks in native bindings that
  // become inert after the first invocation.
  var compiledApi = bindingsAPI.compiledApi;

  compiledApi.once = function(event, listener) {
    if (typeof listener !== 'function')
      throw new TypeError('listener must be a function');
    var fired = false;
    var self = this;

    function g() {
      self.removeListener(event, g);
      if (!fired) {
        fired = true;
        listener.apply(self, arguments);
      }
    }
    this.on(event, g);
    return this;
  };

  compiledApi.on = function(event, callback) {
      if (eventsMap.hasOwnProperty(event)) {
        compiledApi[eventsMap[event]].addListener(callback);
      }

View on GitHub (pinned to e15da848e9)

Solutions

  1. Pass a function: `nw.App.once('open', (path) => {})`.
  2. Guard the call: `if (typeof cb === 'function') nw.App.once(ev, cb);`.

Example fix

// before
nw.App.once('open', handlers.onOpen);
// after
if (typeof handlers.onOpen === 'function') nw.App.once('open', handlers.onOpen);
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof listener !== 'function') throw new TypeError('listener must be a function');

Type guard

function isListener(v) { return typeof v === 'function'; }

Try / catch

try { nw.App.once(ev, cb); } catch (e) { if (/listener/.test(e.message)) console.warn('Skipped non-function listener'); else throw e; }

Prevention

When it happens

Trigger: Calling `nw.App.once('argv', undefined)`, `nw.App.once('open', 'handler')`, or passing a value from an optional config that defaulted to null.

Common situations: Passing a handler looked up by name that did not resolve; copy-paste from an API that accepts a string event name as the listener.

Related errors


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