affaan-m/ECC · error
Invalid install config
Error message
Invalid install config ${resolvedPath}: ${formatValidationErrors(validator.errors)} What it means
loadInstallConfig() reads the config JSON and validates it with a schema validator (getValidator()). When validator(raw) returns false it throws this error including the resolved path and the formatted list of validation errors. It signals the config exists but its contents violate the expected schema.
Solutions
- Read the formatValidationErrors output in the message and fix each listed field in the config file.
- Regenerate or restore the config from the repository's shipped default (manifests/install-components.json / install-modules.json area) and re-apply your customizations.
- If you upgraded ECC, migrate your config to the current schema per the release notes rather than reusing the old file.
- Validate the JSON parses and matches the expected shape with a quick node -e check before rerunning the installer.
Example fix
// before (config.json)
{ "modules": "agents,skills" }
// after
{ "modules": ["agents", "skills"] } Defensive patterns
Strategy: validation
Validate before calling
const raw = JSON.parse(fs.readFileSync(configPath, 'utf8'));
const required = ['modules'];
const missing = required.filter(k => !(k in raw));
if (missing.length) throw new Error(`Install config missing fields: ${missing.join(', ')}`); Type guard
function isValidInstallConfig(raw) {
return !!raw && typeof raw === 'object' && !Array.isArray(raw)
&& Array.isArray(raw.modules)
&& raw.modules.every(m => typeof m === 'string' && m.length > 0);
} Try / catch
try {
const config = loadInstallConfig(configPath);
} catch (err) {
if (err.message.startsWith('Invalid install config')) {
console.error(err.message); // includes formatted validation errors
process.exitCode = 1;
} else throw err;
} Prevention
- Start from the shipped default config and edit incrementally rather than writing one from scratch.
- After upgrading ECC, diff your config against the current default schema before running installs.
- Keep configs in version control so mistakes are diffable and reversible.
- Run a JSON schema check or the repo's own validator on the config in CI.
When it happens
Trigger: Calling loadInstallConfig() with a JSON file whose fields are missing, misspelled, or of the wrong type; supplying an install config from an older ECC version that predates new required fields; hand-editing the config and dropping a required key.
Common situations: Schema drift after upgrading ECC (config written for an older version); manual edits removing or renaming required keys; copying a config from another project with different shape; valid JSON but wrong structure (e.g. modules as a string instead of an array).
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- MCP config must include an mcpServers object
- workflow schema_version must be 1
- -32602
- application config exceeds local size limit
- artifact path must be a non-empty relative path
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/3538e5e901f9c145.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install/config.js:69
function findDefaultInstallConfigPath(options = {}) {
const cwd = options.cwd || process.cwd();
const candidatePath = path.join(cwd, DEFAULT_INSTALL_CONFIG);
return fs.existsSync(candidatePath) ? candidatePath : null;
}
function loadInstallConfig(configPath, options = {}) {
const resolvedPath = resolveInstallConfigPath(configPath, options);
if (!fs.existsSync(resolvedPath)) {
throw new Error(`Install config not found: ${resolvedPath}`);
}
const raw = readJson(resolvedPath, path.basename(resolvedPath));
const validator = getValidator();
if (!validator(raw)) {
throw new Error(
`Invalid install config ${resolvedPath}: ${formatValidationErrors(validator.errors)}`
);
}
return {
path: resolvedPath,
version: raw.version,
target: raw.target || null,
profileId: raw.profile || null,
moduleIds: dedupeStrings(raw.modules),
includeComponentIds: dedupeStrings(raw.include),
excludeComponentIds: dedupeStrings(raw.exclude),
options: raw.options && typeof raw.options === 'object' ? { ...raw.options } : {},
};
}
module.exports = {
DEFAULT_INSTALL_CONFIG,View on GitHub (pinned to 8321021c54)