affaan-m/ECC · error
No install profile, module IDs, or included component IDs…
Error message
No install profile, module IDs, or included component IDs were provided
What it means
resolveInstallPlan requires a non-empty source of modules to install: after collecting profile modules, explicit module IDs, and included component IDs, if nothing was requested it throws. An install plan must be based on at least one of these three inputs.
Solutions
- Pass a valid profileId (e.g. 'standard')
- Or supply explicit module IDs via the modules option
- Or include at least one component ID via includeComponentIds
- Add a default profile in your CLI wrapper when the user omits flags
Example fix
// before
resolveInstallPlan({ target: 'claude-code' })
// after
resolveInstallPlan({ target: 'claude-code', profileId: 'standard' }) Defensive patterns
Strategy: validation
Validate before calling
const hasSource = options.profileId
|| (options.includeModuleIds?.length ?? 0) > 0
|| (options.includeComponentIds?.length ?? 0) > 0;
if (!hasSource) throw new Error('provide --profile, modules, or include components'); Type guard
function hasInstallSource(o) {
return Boolean(o.profileId)
|| (Array.isArray(o.includeModuleIds) && o.includeModuleIds.length > 0)
|| (Array.isArray(o.includeComponentIds) && o.includeComponentIds.length > 0);
} Try / catch
try {
const plan = resolveInstallPlan(options);
} catch (err) {
if (err.message.startsWith('No install profile, module IDs,')) {
console.error('Specify a profile (--profile standard) or at least one module/component.'); process.exitCode = 2;
} else throw err;
} Prevention
- Make your CLI require at least one of --profile/--include/--module
- Default to a standard profile when no selection flags are given
- Document the three selection sources in usage text
When it happens
Trigger: Calling resolveInstallPlan() with no profileId, no includeModuleIds, and no includeComponentIds (all empty after dedupe/normalization).
Common situations: Invoking the plan CLI without any of --profile/--include/--module flags, a config file that lost its profile key, or programmatic callers passing all-empty options.
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
- At least one guided harness must be selected
- No install profile, module IDs, included components, or…
- No legacy languages were provided
- all overlays must be readable local files
- all takes must be readable local files
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/a1570b032c4934e4.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install-manifests.js:618
const validatedProjectRoot = readOptionalStringOption(options, 'projectRoot');
const validatedHomeDir = readOptionalStringOption(options, 'homeDir');
const targetPlanningInput = target
? {
repoRoot: manifests.repoRoot,
projectRoot: validatedProjectRoot || manifests.repoRoot,
homeDir: validatedHomeDir || os.homedir(),
env: resolveInvocationEnvironment(options),
}
: null;
const targetAdapter = target ? getInstallTargetAdapter(target) : null;
const effectiveRequestedIds = dedupeStrings(
requestedModuleIds.filter(moduleId => !excludedModuleOwners.has(moduleId))
);
if (requestedModuleIds.length === 0) {
throw new Error('No install profile, module IDs, or included component IDs were provided');
}
if (effectiveRequestedIds.length === 0) {
throw new Error('Selection excludes every requested install module');
}
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) {View on GitHub (pinned to 8321021c54)