{"record":{"id":"19b7323844cd864c","repo":"affaan-m/ECC","slug":"an-install-config-path-is-required","errorCode":null,"errorMessage":"An install config path is required","messagePattern":"An install config path is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/install/config.js","lineNumber":41,"sourceCode":"  }\n\n  const schema = readJson(CONFIG_SCHEMA_PATH, 'ecc-install-config.schema.json');\n  const ajv = new Ajv({ allErrors: true });\n  cachedValidator = ajv.compile(schema);\n  return cachedValidator;\n}\n\nfunction dedupeStrings(values) {\n  return [...new Set((Array.isArray(values) ? values : []).map(value => String(value).trim()).filter(Boolean))];\n}\n\nfunction formatValidationErrors(errors = []) {\n  return errors.map(error => `${error.instancePath || '/'} ${error.message}`).join('; ');\n}\n\nfunction resolveInstallConfigPath(configPath, options = {}) {\n  if (!configPath) {\n    throw new Error('An install config path is required');\n  }\n\n  const cwd = options.cwd || process.cwd();\n  return path.isAbsolute(configPath)\n    ? configPath\n    : path.normalize(path.join(cwd, configPath));\n}\n\nfunction findDefaultInstallConfigPath(options = {}) {\n  const cwd = options.cwd || process.cwd();\n  const candidatePath = path.join(cwd, DEFAULT_INSTALL_CONFIG);\n  return fs.existsSync(candidatePath) ? candidatePath : null;\n}\n\nfunction loadInstallConfig(configPath, options = {}) {\n  const resolvedPath = resolveInstallConfigPath(configPath, options);\n\n  if (!fs.existsSync(resolvedPath)) {","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/install/config.js#L23-L59","documentation":"Thrown by resolveInstallConfigPath in scripts/lib/install/config.js when configPath is falsy. The resolver does not fall back to a default — that is the caller's job (findDefaultInstallConfigPath returns the candidate path or null). Any caller that forwards an optional --config flag straight into loadInstallConfig without first resolving a default will hit this.","triggerScenarios":"Calling loadInstallConfig(null) or loadInstallConfig('') without first calling findDefaultInstallConfigPath to discover an ecc-install.json in cwd.","commonSituations":"A CLI that made --config optional but forwards undefined; a wrapper script that reads options.config from an unset env var; a programmatic caller that assumed the loader has a built-in default.","solutions":["Before calling loadInstallConfig, resolve the path: const cfg = configPath || findDefaultInstallConfigPath({ cwd }); if (!cfg) throw ...","Make --config required in your CLI when no default exists.","Pass a non-empty string (absolute or relative)."],"exampleFix":"// before\nconst config = loadInstallConfig(options.config);\n\n// after\nconst configPath = options.config || findDefaultInstallConfigPath({ cwd: process.cwd() });\nif (!configPath) {\n  throw new Error('No install config specified and no ecc-install.json found in cwd');\n}\nconst config = loadInstallConfig(configPath, { cwd: process.cwd() });","handlingStrategy":"validation","validationCode":"function requireConfigPath(configPath, options = {}) {\n  return configPath || findDefaultInstallConfigPath(options);\n}\nconst p = requireConfigPath(options.config, { cwd: process.cwd() });\nif (!p) {\n  throw new Error('No install config specified and no ecc-install.json found in cwd');\n}","typeGuard":"function isNonEmptyString(v) {\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always pair an optional --config CLI flag with findDefaultInstallConfigPath so an unset flag still resolves.","Print a helpful error if neither the flag nor a default config exists.","Document the default ecc-install.json lookup location for users."],"tags":["install-config","missing-argument"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}