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
- Read the message: it names the depending module and the excluding components — drop the relevant exclude.
- Switch from component-level exclude to skipping the depending module entirely.
- Inspect the dependency graph (module.dependencies in install-modules.json) before excluding.
- 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
- Before excluding a component, inspect the dependency graph in install-modules.json.
- Prefer excluding leaf modules over baseline/lang components that others depend on.
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
- Unknown install component: ${componentId}
- Unknown install module: ${moduleId}
- Circular install dependency detected at ${moduleId}
- Failed to parse ${label} at ${filePath}: ${error.message}
- Invalid ${label} at ${filePath}: expected a JSON object
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/1b1978882778d35e.
Report an issue: GitHub.