affaan-m/ECC · error
--no-hooks cannot be combined with an explicit…
Error message
--no-hooks cannot be combined with an explicit hooks-runtime module selection
What it means
normalizeInstallRequest resolves hook consent flags via resolveHookConsentFlags. If the user explicitly declined hooks (`--no-hooks`, consent === 'declined') while the merged moduleIds explicitly include the 'hooks-runtime' module, the request is self-contradictory and throws this error.
Solutions
- Remove 'hooks-runtime' from the module list (CLI --module args and any config moduleIds) when using --no-hooks.
- Drop the --no-hooks flag if you actually want hooks installed.
- Edit your install config file to remove the hooks-runtime entry if it's the source of the conflict.
- Use --enable-hooks explicitly if hook consent ambiguity is the issue.
Example fix
// before install --no-hooks --module hooks-runtime // after install --no-hooks // hooks-runtime removed from module selection // or install --module hooks-runtime // --no-hooks removed
Defensive patterns
Strategy: validation
Validate before calling
const merged = [...(config?.moduleIds || []), ...(options.moduleIds || [])];
if (options.noHooks && merged.includes('hooks-runtime')) {
throw new Error('--no-hooks conflicts with an explicit hooks-runtime module selection');
} Type guard
function hooksSelectionConsistent(opts) {
return !(resolveHookConsentFlags(opts) === 'declined'
&& [...(opts.moduleIds || [])].includes('hooks-runtime'));
} Try / catch
try {
const req = normalizeInstallRequest(options);
} catch (e) {
if (e.message.includes('--no-hooks cannot be combined')) {
console.error('Remove hooks-runtime from module selection or drop --no-hooks.');
return;
}
throw e;
} Prevention
- Never combine --no-hooks with a module list containing hooks-runtime.
- Audit config-file moduleIds when overriding consent on the command line — options and config are merged.
- Express 'no hooks' by omitting hooks-runtime rather than passing --no-hooks with explicit selections.
- Add a pre-flight consistency check in wrapper scripts that merge flags from multiple sources.
When it happens
Trigger: Calling normalizeInstallRequest with options like `{ noHooks: true, moduleIds: ['hooks-runtime'] }` or CLI `install --no-hooks --module hooks-runtime`; also when a config file lists hooks-runtime in moduleIds while --no-hooks is passed on the command line (options and config moduleIds are merged before the check).
Common situations: A saved install config that includes hooks-runtime while the user passes --no-hooks to disable hooks for one run; combining a profile or module list that bundles hooks-runtime with --no-hooks; scripting flags from different sources that disagree.
Understand the failure class
Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.
Related errors
- INVALID_HOOK_MODE
- Legacy language arguments cannot be combined with…
- --locale can only be used with --target claude or --target…
- The all/* harness selection cannot be combined with other…
- all overlays must be readable local files
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/84c5b5ae3b64f34e.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install/request.js:131
const requestedIncludeComponentIds = dedupeStrings([
...(config?.includeComponentIds || []),
...(options.includeComponentIds || []),
]);
const includeComponentIds = dedupeStrings([
...requestedIncludeComponentIds,
...(localeComponentId ? [localeComponentId] : []),
]);
const excludeComponentIds = dedupeStrings([
...(config?.excludeComponentIds || []),
...(options.excludeComponentIds || []),
]);
const legacyLanguages = dedupeStrings(dedupeStrings([
...(Array.isArray(options.legacyLanguages) ? options.legacyLanguages : []),
...(Array.isArray(options.languages) ? options.languages : []),
]).map(language => language.toLowerCase()));
const hookConsent = resolveHookConsentFlags(options);
if (hookConsent === 'declined' && moduleIds.includes('hooks-runtime')) {
throw new Error('--no-hooks cannot be combined with an explicit hooks-runtime module selection');
}
const hasManifestBaseSelection = Boolean(profileId) || moduleIds.length > 0 || includeComponentIds.length > 0;
const hasNonLocaleManifestSelection = Boolean(profileId)
|| moduleIds.length > 0
|| requestedIncludeComponentIds.length > 0
|| excludeComponentIds.length > 0;
const usingManifestMode = hasManifestBaseSelection || excludeComponentIds.length > 0;
if (hasNonLocaleManifestSelection && legacyLanguages.length > 0) {
throw new Error(
'Legacy language arguments cannot be combined with --profile, --modules, --with, --without, or manifest config selections'
);
}
if (!options.help && !hasManifestBaseSelection && legacyLanguages.length === 0) {
throw new Error('No install profile, module IDs, included components, or legacy languages were provided');
}
View on GitHub (pinned to 8321021c54)