nwjs/nw.js · error · TypeError
Invaild parameter, need Shortcut object.
Error message
Invaild parameter, need Shortcut object.
What it means
Thrown by nw.App.registerGlobalHotKey() when the argument is not an instance of nw.Shortcut. The guard calls v8_util.getConstructorName(shortcut) and compares it to the literal string "Shortcut", so plain objects, primitive values, or objects built in a different JS realm all fail. This protects the native RegisterGlobalHotKey call, which immediately dereferences shortcut.id. The message itself contains a typo ("Invaild").
Source
Thrown at src/api/app/app.js:86
App.prototype.getProxyForURL = function (url) {
return nw.callStaticMethodSync('App', 'getProxyForURL', [ url ]);
}
App.prototype.setProxyConfig = function (proxy_config) {
return nw.callStaticMethodSync('App', 'SetProxyConfig', [ proxy_config ]);
}
App.prototype.addOriginAccessWhitelistEntry = function(sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains) {
return nw.callStaticMethodSync('App', 'AddOriginAccessWhitelistEntry', sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains);
}
App.prototype.removeOriginAccessWhitelistEntry = function(sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains) {
return nw.callStaticMethodSync('App', 'RemoveOriginAccessWhitelistEntry', sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains);
}
App.prototype.registerGlobalHotKey = function(shortcut) {
if (v8_util.getConstructorName(shortcut) != "Shortcut")
throw new TypeError("Invaild parameter, need Shortcut object.");
return nw.callStaticMethodSync('App',
'RegisterGlobalHotKey',
[ shortcut.id ])[0];
}
App.prototype.unregisterGlobalHotKey = function(shortcut) {
if (v8_util.getConstructorName(shortcut) != "Shortcut")
throw new TypeError("Invaild parameter, need Shortcut object.");
nw.callStaticMethodSync('App', 'UnregisterGlobalHotKey', [ shortcut.id ]);
}
App.prototype.__defineGetter__('argv', function() {
if (!argv) {
var fullArgv = this.fullArgv;
argv = [];
for (var i = 0; i < fullArgv.length; ++i) {View on GitHub (pinned to e15da848e9)
Solutions
- Build the value with `new nw.Shortcut({ key: 'Ctrl+A', active: fn, failed: fn })` and pass that instance.
- If the shortcut originates in another frame, re-create it in the main node context before registering.
- Keep the Shortcut reference in a variable so the same instance can be passed to unregisterGlobalHotKey later.
Example fix
// before
nw.App.registerGlobalHotKey({ key: 'Ctrl+Shift+P', active: onActive });
// after
var sc = new nw.Shortcut({ key: 'Ctrl+Shift+P', active: onActive, failed: onFail });
nw.App.registerGlobalHotKey(sc); Defensive patterns
Strategy: type-guard
Validate before calling
function isShortcut(v) {
return v instanceof nw.Shortcut;
}
// before registering:
if (!isShortcut(sc)) sc = new nw.Shortcut(sc);
nw.App.registerGlobalHotKey(sc); Type guard
function isShortcut(v) {
return v != null && typeof v === 'object' &&
(v instanceof nw.Shortcut ||
(v.constructor && v.constructor.name === 'Shortcut'));
} Try / catch
try {
nw.App.registerGlobalHotKey(sc);
} catch (e) {
if (e instanceof TypeError && /Shortcut object/.test(e.message)) {
sc = new nw.Shortcut(sc); // coerce and retry once
nw.App.registerGlobalHotKey(sc);
} else { throw e; }
} Prevention
- Centralize shortcut creation in one factory that always returns new nw.Shortcut(...).
- Store every registered Shortcut instance so unregister uses the same reference.
- Build shortcuts in the main node context, not in webviews/iframes.
When it happens
Trigger: Calling nw.App.registerGlobalHotKey(undefined), registerGlobalHotKey({key:'Ctrl+A'}), or registerGlobalHotKey('Ctrl+A'). Also triggered when the shortcut object was created in another frame/webview and passed across contexts, because the constructor-name string no longer matches.
Common situations: Developers hand-build the shortcut object ({key, active, failed}) instead of using the nw.Shortcut constructor; they pass the raw key string; or a refactor that moves Shortcut creation into an iframe/window breaks the cross-realm constructor check.
Related errors
- Type of '{type}' is not supported
- Only support getting plain text from Clipboard
- Menu.append() requires a valid MenuItem
- 'submenu' must be a valid Menu
- 'click' must be a valid Function
AI-assisted analysis of nwjs/nw.js@e15da848e9 (2026-08-13).
Data as JSON: /api/errors/b54d1239277eb07b.
Report an issue: GitHub.