{"id":"8c21482278aa5b5b","repo":"tj/commander.js","slug":"unexpected-value-for-event-passed-to-hook-eve","errorCode":null,"errorMessage":"Unexpected value for event passed to hook : '${event}'.\nExpecting one of '${allowedValues.join(\"', '\")}'","messagePattern":"Unexpected value for event passed to hook : '(.+?)'\\.\nExpecting one of '(.+?)'","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/command.js","lineNumber":491,"sourceCode":"        this.helpCommand(undefined, undefined); // use default name and description\n      }\n      return this._helpCommand;\n    }\n    return null;\n  }\n\n  /**\n   * Add hook for life cycle event.\n   *\n   * @param {string} event\n   * @param {Function} listener\n   * @return {Command} `this` command for chaining\n   */\n\n  hook(event, listener) {\n    const allowedValues = ['preSubcommand', 'preAction', 'postAction'];\n    if (!allowedValues.includes(event)) {\n      throw new Error(`Unexpected value for event passed to hook : '${event}'.\nExpecting one of '${allowedValues.join(\"', '\")}'`);\n    }\n    if (this._lifeCycleHooks[event]) {\n      this._lifeCycleHooks[event].push(listener);\n    } else {\n      this._lifeCycleHooks[event] = [listener];\n    }\n    return this;\n  }\n\n  /**\n   * Register callback to use as replacement for calling process.exit.\n   *\n   * @param {Function} [fn] optional callback which will be passed a CommanderError, defaults to throwing\n   * @return {Command} `this` command for chaining\n   */\n\n  exitOverride(fn) {","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/tj/commander.js/blob/ba6d13ddb4243e5913367734f8c159089ffe7834/lib/command.js#L473-L509","documentation":"Thrown by Command.hook() at lib/command.js:490-493 when the `event` argument is not one of the supported lifecycle events: 'preSubcommand', 'preAction', or 'postAction'. Hooks are stored keyed by event in _lifeCycleHooks, so an unknown event would silently never fire — Commander fails fast instead.","triggerScenarios":"Calling `.hook('preParse', fn)`, `.hook('beforeAction', fn)`, or any string outside the allow-list. Typos like 'preaction' (lowercase) vs 'preAction' (camelCase) also trip it because the check is case-sensitive.","commonSituations":"Version skew: an older Commander version had fewer hook events and code was written against different names; copy-pasting hook names from a blog post that used non-existent events; assuming symmetric 'pre'/'post' naming for every phase.","solutions":["Use one of the documented events exactly: 'preSubcommand', 'preAction', or 'postAction' (case-sensitive).","Upgrade/downgrade to align Commander version with the event names your code assumes.","If you need a phase Commander doesn't expose (e.g. pre-parse), use the action handler itself or wrap program.parse."],"exampleFix":"// before (throws)\n.hook('preParse', (cmd, opts) => { /* ... */ })\n\n// after\n.hook('preAction', (cmd, opts) => { /* ... */ })","handlingStrategy":"type-guard","validationCode":"const HOOK_EVENTS = ['preSubcommand', 'preAction', 'postAction'];\nfunction registerHook(cmd, event, fn) {\n  if (!HOOK_EVENTS.includes(event)) {\n    throw new TypeError(`hook event must be one of ${HOOK_EVENTS.join(', ')}`);\n  }\n  cmd.hook(event, fn);\n}","typeGuard":"type HookEvent = 'preSubcommand' | 'preAction' | 'postAction';\nfunction isHookEvent(v: unknown): v is HookEvent {\n  return v === 'preSubcommand' || v === 'preAction' || v === 'postAction';\n}","tryCatchPattern":null,"preventionTips":["Pin the Commander version to match the hook names your code uses.","Drive hook registration from a typed const, not free-form strings.","Double-check camelCase: 'preAction' not 'preaction'."],"tags":["commander","hook","lifecycle","configuration"],"analyzedSha":"ba6d13ddb4243e5913367734f8c159089ffe7834","analyzedAt":"2026-08-03T20:26:04.326Z","schemaVersion":2}