nwjs/nw.js · error · TypeError
only following event can be listened: displayBoundsChanged,
Error message
only following event can be listened: displayBoundsChanged, displayAdded, displayRemoved
What it means
Screen overrides `on`/`addListener` and rejects any event name outside its whitelist. Note a discrepancy: the condition ALSO accepts 'chooseDesktopMedia', but the error message lists only the three display events — so the message under-reports the allowed set. Any other event name throws a TypeError.
Source
Thrown at src/api/screen/screen.js:32
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IM
// PLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
// S FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
// OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH
// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
var screenInstance = null;
function Screen() {
nw.allocateObject(this, {});
this._numListener = 0;
}
require('util').inherits(Screen, exports.Base);
// Override the addListener method.
Screen.prototype.on = Screen.prototype.addListener = function(ev, callback) {
if ( ev != "displayBoundsChanged" && ev != "displayAdded" && ev != "displayRemoved" && ev != "chooseDesktopMedia")
throw new TypeError('only following event can be listened: displayBoundsChanged, displayAdded, displayRemoved');
var onRemoveListener = function (type, listener) {
if (this._numListener > 0) {
this._numListener--;
if (this._numListener == 0) {
process.EventEmitter.prototype.removeListener.apply(this, ["removeListener", onRemoveListener]);
nw.callStaticMethodSync('Screen', 'RemoveScreenChangeCallback', [ this.id ]);
}
}
};
if(this._numListener == 0) {
if (nw.callStaticMethodSync('Screen', 'AddScreenChangeCallback', [ this.id ])[0] == false ) {
throw new Error('nw.callStaticMethodSync(Screen, AddScreenChangeCallback) fails');
return;
}
process.EventEmitter.prototype.addListener.apply(this, ["removeListener", onRemoveListener]);
}View on GitHub (pinned to e15da848e9)
Solutions
- Use one of the supported events: 'displayBoundsChanged', 'displayAdded', 'displayRemoved' (and 'chooseDesktopMedia' for the dedicated API).
- Copy event names exactly, including camelCase and the trailing 'Changed'/'Added'/'Removed'.
- For desktop-media capture, prefer nw.Screen.chooseDesktopMedia(...) which wires the callback internally.
Example fix
// before
nw.Screen.on('displays-changed', fn); // throws
// after
nw.Screen.on('displayBoundsChanged', fn);
nw.Screen.on('displayAdded', fn);
nw.Screen.on('displayRemoved', fn); Defensive patterns
Strategy: validation
Validate before calling
var SCREEN_EVENTS = ['displayBoundsChanged', 'displayAdded', 'displayRemoved', 'chooseDesktopMedia'];
function onScreen(ev, cb) {
if (SCREEN_EVENTS.indexOf(ev) === -1)
throw new TypeError('Unsupported screen event: ' + ev);
nw.Screen.on(ev, cb);
} Type guard
function isScreenEvent(ev) {
return ['displayBoundsChanged','displayAdded','displayRemoved','chooseDesktopMedia'].indexOf(ev) !== -1;
} Try / catch
try { nw.Screen.on(ev, cb); }
catch (e) {
if (e instanceof TypeError && /only following event/.test(e.message)) {
console.warn('Ignoring unsupported screen event:', ev);
} else throw e;
} Prevention
- Copy event names exactly (camelCase, correct suffixes).
- Note 'chooseDesktopMedia' is allowed even though the message omits it.
- Centralize screen-event subscription in one module.
When it happens
Trigger: Calling nw.Screen.on('resize', fn), .on('change', fn), or any custom event. Even a typo like 'displayBoundChanged' (missing 's') throws.
Common situations: Assuming Screen is a general EventEmitter and listening for arbitrary names. Migrating from Electron's `screen.on('display-metrics-changed')`. Typos in the long event names.
Related errors
- Invalid menu type: {option.type}
- Invalid option.
- Invalid MenuItem type: {option.type}
- A normal MenuItem must have a label
- 'checked' property is only available for checkbox
AI-assisted analysis of nwjs/nw.js@e15da848e9 (2026-08-13).
Data as JSON: /api/errors/b21a5431eb5b64c4.
Report an issue: GitHub.