{"record":{"id":"34f46a4d647da04c","repo":"nwjs/nw.js","slug":"active-must-be-a-valid-function","errorCode":null,"errorMessage":"'active' must be a valid function.","messagePattern":"'active' must be a valid function\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/api/shortcut/shorcut.js","lineNumber":35,"sourceCode":"// OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WH\n// ETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar v8_util = process.binding('v8_util');\n\nfunction Shortcut(option) {\n  if (typeof option != 'object')\n    throw new TypeError('Invalid option.');\n\n  if (!option.hasOwnProperty('key'))\n    throw new TypeError(\"Shortcut requires 'key' to specify key combinations.\");\n\n  option.key = String(option.key);\n  this.key = option.key;\n\n  if (option.hasOwnProperty('active')) {\n    if (typeof option.active != 'function')\n      throw new TypeError(\"'active' must be a valid function.\");\n    else\n      this.active = option.active;\n  }\n\n  if (option.hasOwnProperty('failed')) {\n    if (typeof option.failed != 'function')\n      throw new TypeError(\"'failed' must be a valid function.\");\n    else\n      this.failed = option.failed;\n  }\n\n  v8_util.setHiddenValue(this, 'option', option);\n  nw.allocateObject(this, option);\n}\n\nrequire('util').inherits(Shortcut, exports.Base);\n\nShortcut.prototype.handleEvent = function(ev) {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/nwjs/nw.js/blob/e15da848e9e08e6e467532dae78995c6ad2f55ee/src/api/shortcut/shorcut.js#L17-L53","documentation":"Thrown by the nw.Shortcut constructor when the 'active' option key is present but its value is not a function. nw.Shortcut binds a global key accelerator and invokes 'active' on registration success, so it must be callable. The typeof check rejects strings, objects, numbers, and undefined-after-coercion values.","triggerScenarios":"Calling `new nw.Shortcut({ key: 'Ctrl+Shift+A', active: 'someString' })`, passing an arrow stored in a variable that is actually undefined, or passing `active: { handle: fn }` instead of the function itself.","commonSituations":"Passing a method reference from an object that hasn't been initialized; deserializing shortcut config from JSON where functions become strings; migrating from a config that stored handler names instead of references.","solutions":["Ensure option.active is a function: `new nw.Shortcut({ key, active: () => {} })`.","If you only want failure handling, omit 'active' entirely and provide 'failed' instead.","If loading handlers dynamically, resolve the string name to a real function reference before constructing the Shortcut."],"exampleFix":"// before\nnew nw.Shortcut({ key: 'Ctrl+A', active: 'onActive' });\n// after\nnew nw.Shortcut({ key: 'Ctrl+A', active: onActive });","handlingStrategy":"type-guard","validationCode":"if (option && option.hasOwnProperty('active') && typeof option.active !== 'function') {\n  throw new Error('option.active must be a function');\n}","typeGuard":"function isShortcutOption(o) {\n  return o && typeof o === 'object' &&\n    typeof o.key !== 'undefined' &&\n    (!o.hasOwnProperty('active') || typeof o.active === 'function') &&\n    (!o.hasOwnProperty('failed') || typeof o.failed === 'function');\n}","tryCatchPattern":"try { new nw.Shortcut(opt); } catch (e) { if (e instanceof TypeError) console.warn('Bad shortcut option:', e.message); else throw e; }","preventionTips":["Always pass handler references, never string names.","Centralize shortcut construction behind a factory that validates handlers."],"tags":["shortcut","constructor","type-check","nwjs"],"backgroundTag":null,"analyzedSha":"e15da848e9e08e6e467532dae78995c6ad2f55ee","analyzedAt":"2026-08-13T04:15:35.452Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}