affaan-m/ECC · error · Error

Module ${dependencyOf} depends on excluded module ${moduleId

Error message

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

What it means

Thrown by resolveModule() when a module is reached as a dependency of another module (dependencyOf is set) AND that module id is in the excludedModuleOwners map. Direct root-level excludes are silently dropped, but a dependency exclude would leave the depending module broken, so it is a hard error. The message names both the depending module and the components that excluded the dependency.

Source

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

  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 01e15490f0)

Solutions

  1. Read the message: it names the depending module and the excluding components — drop the relevant exclude.
  2. Switch from component-level exclude to skipping the depending module entirely.
  3. Inspect the dependency graph (module.dependencies in install-modules.json) before excluding.
  4. If the exclude is target-default, pass an explicit profileId that does not pull in the dependent module.

Example fix

// before
resolveInstallPlan({
  target: 'claude',
  includeComponentIds: ['capability:semantic-search'], // depends on rules-core
  excludeComponentIds: ['baseline:rules'],            // excludes rules-core
});
// after — keep the dependency
resolveInstallPlan({ target: 'claude', includeComponentIds: ['capability:semantic-search'] });
Defensive patterns

Strategy: try-catch

Validate before calling

const { loadInstallManifests } = require('./scripts/lib/install-manifests');
const manifests = loadInstallManifests(options);
const excludedModuleIds = new Set(expandToModules(options.excludeComponentIds || [], manifests));
const requestedModuleIds = expandToModules(options.includeComponentIds || [], manifests);
const dependents = collectDependents(requestedModuleIds, manifests);
const conflict = [...excludedModuleIds].filter(id => dependents.has(id));
if (conflict.length > 0) {
  throw new Error(`Cannot exclude ${conflict.join(', ')} — needed by requested modules`);
}

Try / catch

try {
  return resolveInstallPlan(options);
} catch (err) {
  if (/depends on excluded module/.test(err.message)) {
    // strip the offending exclude and retry, or surface to user
    throw err;
  }
  throw err;
}

Prevention

When it happens

Trigger: Excluding component 'lang:rust' while including a profile/component whose module declares a dependency on a rust module; target-default exclusions that drop a module another selected module depends on.

Common situations: User excludes a 'baseline' or 'lang' component thinking it is optional when a selected capability module depends on it; OpenCode default exclusions intersect a dependency of a requested module.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/1b1978882778d35e. Report an issue: GitHub.