affaan-m/ECC · error

Module depends on excluded module )` : ''}

Error message

Module ${dependencyOf} depends on excluded module ${moduleId}${owners.length > 0 ? ` (excluded by ${owners.join(', ')})` : ''}

What it means

resolveInstallPlan throws this when a requested module's dependency chain reaches a module that has been excluded (by profile exclusions or target default exclusions), and the excluded module is reached as a dependency rather than directly. Directly-excluded requests are silently filtered out, but a hard dependency on an excluded module is a plan conflict the installer cannot resolve, so it names both the depending module and the exclusion owners.

Solutions

  1. Remove the module that depends on the excluded module from the request, or pick a different module
  2. Un-exclude the dependency (remove it from profile exclusions or pick a target that does not default-exclude it)
  3. Fix manifests/install-modules.json so the depending module no longer lists the excluded dependency
  4. Read the message: moduleId is the excluded dependency, dependencyOf is the depending module, and owners names who excluded it

Example fix

// before (profile)
{ "modules": ["mcp-configs"], "exclude": ["mcp-configs-context7"] }
// after — exclude only a module nothing depends on, or drop the exclusion
{ "modules": ["mcp-configs"] }
Defensive patterns

Strategy: validation

Validate before calling

// Before resolving, check that no requested module depends on an excluded one
const excluded = new Set(profile.exclude || []);
for (const id of requestedModules) {
  for (const dep of manifests.modulesById.get(id).dependencies) {
    if (excluded.has(dep)) throw new Error(`${id} depends on excluded ${dep}`);
  }
}

Try / catch

try {
  const plan = resolveInstallPlan(options);
} catch (e) {
  if (/depends on excluded module/.test(e.message)) {
    // surface the conflict to the user, let them adjust profile exclusions
  } else throw e;
}

Prevention

When it happens

Trigger: Calling resolveInstallPlan (via plan or runTests) with a module that depends on a module listed in the profile's excluded modules or a target's default exclusions — e.g. installing module A when A's `dependencies` array includes a module excluded for the chosen target.

Common situations: Customizing an install profile with an exclusion like 'docs' or a platform target (e.g. codex) whose default-excluded modules are still depended on by another requested module; editing manifests/install-modules.json and adding a dependency on a module that target adapters exclude.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/1b1978882778d35e. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/install-manifests.js:643

  const selectedIds = new Set();
  const skippedTargetIds = new Set();
  const excludedIds = new Set([
    ...excludedModuleIds,
    ...targetDefaultExclusions.map(exclusion => exclusion.moduleId),
  ]);
  const visitingIds = new Set();
  const resolvedIds = new Set();

  function resolveModule(moduleId, dependencyOf, rootRequesterId) {
    const module = manifests.modulesById.get(moduleId);
    if (!module) {
      throw new Error(`Unknown install module: ${moduleId}`);
    }

    if (excludedModuleOwners.has(moduleId)) {
      if (dependencyOf) {
        const owners = excludedModuleOwners.get(moduleId) || [];
        throw new Error(
          `Module ${dependencyOf} depends on excluded module ${moduleId}${owners.length > 0 ? ` (excluded by ${owners.join(', ')})` : ''}`
        );
      }
      return;
    }

    const supportsTarget = !target
      || (
        readModuleTargetsOrThrow(module).includes(target)
        && (!targetAdapter || targetAdapter.supportsModule(module, targetPlanningInput))
      );

    if (!supportsTarget) {
      if (dependencyOf) {
        skippedTargetIds.add(rootRequesterId || dependencyOf);
        return false;
      }
      skippedTargetIds.add(moduleId);

View on GitHub (pinned to 8321021c54)