{"record":{"id":"a232d02a8c4018dc","repo":"affaan-m/ECC","slug":"invalid-hook-mode","errorCode":"INVALID_HOOK_MODE","errorMessage":"Invalid hook mode: ${options.hooks}","messagePattern":"Invalid hook mode: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/claude-scope-migration.js","lineNumber":254,"sourceCode":"  const plugins = readPluginInventory(run, paths.projectRoot, 'final-verification');\n  return validateExpectedScopes(plugins, [destinationScope], {\n    code: 'FINAL_VERIFICATION_FAILED',\n    destinationScope,\n    message: `Could not verify destination-only ${CURRENT_PLUGIN_ID} state after source cleanup.`,\n    phase: 'final-verification',\n    recovery: recoveryCommands(null, destinationScope),\n  });\n}\n\nfunction migrateClaudePluginScope(options = {}, dependencies = {}) {\n  if (!VALID_SCOPES.has(options.scope)) {\n    throw migrationError(\n      'INVALID_SCOPE',\n      'Scope migration requires --scope user, project, or local.'\n    );\n  }\n  if (options.hooks !== undefined && !VALID_HOOK_MODES.has(options.hooks)) {\n    throw migrationError('INVALID_HOOK_MODE', `Invalid hook mode: ${options.hooks}`);\n  }\n\n  const paths = resolveClaudePaths(options);\n  const settingsPath = path.join(paths.configDir, 'settings.json');\n  const settings = readSettings(settingsPath);\n  assertSafeLocalInventory(paths);\n  assertGitAvailable(\n    { cwd: paths.projectRoot },\n    { spawnSync: dependencies.spawnSync }\n  );\n  const providerRun = dependencies.runClaude || runClaude;\n  const run = options.dryRun\n    ? createDryRunClaudeRunner(providerRun, paths, options)\n    : providerRun;\n  const plugins = readPluginInventory(run, paths.projectRoot, 'inventory');\n  const migration = assertMigrationInventory(plugins, options.scope);\n  const hooks = options.hooks === undefined\n    ? deriveHookMode(settings)","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/claude-scope-migration.js#L236-L272","documentation":"ClaudeSetupError with code INVALID_HOOK_MODE thrown by migrateClaudePluginScope in scripts/lib/claude-scope-migration.js:254, immediately after scope validation. When `options.hooks` is provided it must be one of VALID_HOOK_MODES (imported from claude-plugin-setup); any other hook-mode string is rejected before paths are resolved or settings are read. This guards the hook-installation strategy chosen during migration.","triggerScenarios":"Passing `options.hooks` (e.g. `--hooks <value>`) with a value not in VALID_HOOK_MODES — misspellings, unsupported modes like 'off' or 'auto' if the tool only accepts e.g. 'standard'/'strict', or a hooks value supplied as a non-string/undefined-shaped argument.","commonSituations":"Copy-pasting a hook mode from an older ECC version whose accepted values changed; guessing the mode name instead of checking `ecc setup --help`; passing `--hooks` with an empty value from an unset shell variable.","solutions":["Run `ecc setup --help` (or inspect VALID_HOOK_MODES in scripts/lib/claude-plugin-setup.js) to list accepted hook modes and use one exactly.","Omit the --hooks flag entirely to use the default hook mode — validation only runs when hooks is defined.","Fix shell quoting/variable expansion if the value is coming from an environment variable that is empty or malformed.","Update ECC if you are using hook-mode names from a different version's documentation."],"exampleFix":"// before\n// ecc migrate-scope --scope project --hooks always-on\n\n// after (using a valid mode, or omitting the flag)\n// ecc migrate-scope --scope project --hooks standard\n// ecc migrate-scope --scope project","handlingStrategy":"validation","validationCode":"const { VALID_HOOK_MODES } = require('./claude-plugin-setup');\nif (hooks !== undefined && !VALID_HOOK_MODES.has(hooks)) {\n  throw new Error(`Invalid hook mode: ${hooks}. Valid: ${[...VALID_HOOK_MODES].join(', ')}`);\n}","typeGuard":"function isValidHookMode(v, validModes) { return v === undefined || (typeof v === 'string' && validModes.has(v)); }","tryCatchPattern":"try { await migrateClaudePluginScope({ scope, hooks }) }\ncatch (e) {\n  if (e.code === 'INVALID_HOOK_MODE') { console.error(`${e.message} — omit --hooks for the default`); }\n  else throw e;\n}","preventionTips":["Omit --hooks unless you specifically need a non-default hook mode.","Check VALID_HOOK_MODES (or --help) for the exact accepted values in your ECC version.","Quote shell variables holding the hook mode to avoid empty-string passes.","Keep wrapper scripts in sync with the ECC version's accepted modes."],"tags":["cli","validation","hooks","invalid-argument"],"backgroundTag":"invalid-enum-value","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}