{"record":{"id":"9135e2a95fb66133","repo":"affaan-m/ECC","slug":"enable-hooks-and-no-hooks-are-mutually-exclusive","errorCode":null,"errorMessage":"--enable-hooks and --no-hooks are mutually exclusive","messagePattern":"--enable-hooks and --no-hooks are mutually exclusive","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/install/hook-consent.js","lineNumber":81,"sourceCode":"    || destination.endsWith('/.cursor/hooks.json')\n    || destination.includes('/.cursor/hooks/')\n  );\n}\n\nfunction planMaterializesHookRuntime(plan = {}) {\n  const operations = Array.isArray(plan.operations) ? plan.operations : [];\n  return operations.some(isHookRuntimeOperation);\n}\n\nfunction formatHookCapabilityDisclosure(indent = '  ') {\n  return HOOK_CAPABILITY_GROUPS\n    .map((group, index) => `${indent}${index + 1}. ${group.description}`)\n    .join('\\n');\n}\n\nfunction resolveHookConsentFlags({ enableHooks = false, noHooks = false } = {}) {\n  if (enableHooks && noHooks) {\n    throw new Error('--enable-hooks and --no-hooks are mutually exclusive');\n  }\n  if (enableHooks) {\n    return 'enabled';\n  }\n  if (noHooks) {\n    return 'declined';\n  }\n  return null;\n}\n\nfunction withoutHookRuntimeId(values) {\n  return (Array.isArray(values) ? values : []).filter(value => value !== HOOK_RUNTIME_MODULE_ID);\n}\n\nfunction setStatePreviewHookConsent(statePreview, hookConsent) {\n  if (!statePreview || !statePreview.request) {\n    return statePreview;\n  }","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/install/hook-consent.js#L63-L99","documentation":"resolveHookConsentFlags() maps CLI hook flags to a single consent decision. Passing both --enable-hooks and --no-hooks is contradictory (enable vs decline the hook runtime), so the function throws immediately before any install work happens.","triggerScenarios":"Invoking the installer with both flags on one command line, e.g. `ecc install --enable-hooks --no-hooks`; a wrapper script or npm script that appends one flag unconditionally while the user passes the other.","commonSituations":"Shell aliases or CI scripts with baked-in flags colliding with manual flags; copy-pasting two example commands into one; a teammate's documented command containing --no-hooks while the user adds --enable-hooks to opt in.","solutions":["Remove one of the two flags — pass only --enable-hooks to consent to the hook runtime, or only --no-hooks to install without it.","If flags come from a wrapper script or alias, inspect it (type ecc / cat the script) and remove the hard-coded flag.","Omit both flags to be prompted interactively via the guided installer (ecc install --guided)."],"exampleFix":"// before\necc install --enable-hooks --no-hooks\n// after\necc install --enable-hooks","handlingStrategy":"validation","validationCode":"const flags = process.argv.slice(2);\nif (flags.includes('--enable-hooks') && flags.includes('--no-hooks')) {\n  throw new Error('Pass either --enable-hooks or --no-hooks, not both');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const decision = resolveHookConsentFlags({ enableHooks, noHooks });\n} catch (err) {\n  if (/mutually exclusive/.test(err.message)) {\n    console.error('Choose one: --enable-hooks (install hooks) or --no-hooks (skip them).');\n    process.exitCode = 1;\n  } else throw err;\n}","preventionTips":["Do not hard-code hook flags in shared scripts/aliases; let users pass them explicitly.","Build flag handling from a single options object so duplicates are visible.","Prefer the guided installer when the choice is interactive.","Lint CI commands for conflicting installer flags."],"tags":["cli","flags","hooks"],"backgroundTag":"mutually-exclusive-flags","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"}