affaan-m/ECC · error
Failed to load policy from
Error message
Failed to load policy from ${resolvedPath}: ${error.message} What it means
loadPolicy reads a policy JSON file and throws when the file cannot be read or parsed as JSON, wrapping the underlying fs/JSON error with the resolved path. The library requires a readable, valid JSON policy file to configure labels, review, validation, and branch-model behavior, so unreadable or malformed files are a hard failure.
Solutions
- Verify the resolved path in the message exists and is a readable file (ls -l <path>).
- Run the path through a JSON validator; remove comments/trailing commas — policy files must be strict JSON.
- Pass an absolute path or fix the working directory so the relative path resolves correctly.
- Restore the policy file from version control if it was deleted or corrupted.
Example fix
// before
loadPolicy('./policy.jsonc'); // comments not allowed, file missing
// after
loadPolicy('/abs/path/to/policy.json'); // strict JSON, absolute path Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs');
function policyFileOk(p) {
if (!fs.existsSync(p) || !fs.statSync(p).isFile()) return false;
try { JSON.parse(fs.readFileSync(p, 'utf8')); return true; } catch { return false; }
}
if (!policyFileOk(policyPath)) throw new Error(`Policy file missing or invalid JSON: ${policyPath}`); Type guard
null
Try / catch
let policy;
try {
policy = loadPolicy(path);
} catch (e) {
if (e.message.startsWith('Failed to load policy')) {
console.error(`Check that ${path} exists, is readable, and is strict JSON.`, e.message);
process.exitCode = 1;
} else { throw e; }
} Prevention
- Use absolute paths for policy files.
- Commit policy files and CI-check them with a JSON validator.
- Never add comments or trailing commas — policy must be strict JSON.
- Verify the working directory when using relative paths.
When it happens
Trigger: Calling loadPolicy (via policy or result paths) with a path that does not exist, lacks read permission, is a directory, or contains invalid JSON (comments, trailing commas, BOM issues).
Common situations: Relative path resolved from the wrong working directory, config file renamed/deleted, team member committing an invalid policy with comments, wrong file extension or path typo in the config flag/env var.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- candidate configuration exceeds 1 MiB
- Cannot merge ECC configuration at
- Cannot merge ECC configuration into invalid JSON at
- Failed to parse
- Failed to read
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/8e8b99756ed45d84.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/github-coordination/policy.js:66
});
function loadPolicy(rootDir = process.cwd(), configPath = null) {
const resolvedPath = configPath
? path.resolve(configPath)
: path.join(rootDir, 'config', DEFAULT_CONFIG_FILE);
if (!fs.existsSync(resolvedPath)) {
return {
...DEFAULT_POLICY,
sourcePath: null,
};
}
let parsed;
try {
parsed = JSON.parse(fs.readFileSync(resolvedPath, 'utf8'));
} catch (error) {
throw new Error(`Failed to load policy from ${resolvedPath}: ${error.message}`);
}
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
throw new Error(`Policy file ${resolvedPath} must contain a JSON object, got ${Array.isArray(parsed) ? 'array' : typeof parsed}`);
}
const labels = typeof parsed.labels === 'object' && parsed.labels !== null && !Array.isArray(parsed.labels) ? parsed.labels : {};
const review = typeof parsed.review === 'object' && parsed.review !== null && !Array.isArray(parsed.review) ? parsed.review : {};
const validation = typeof parsed.validation === 'object' && parsed.validation !== null && !Array.isArray(parsed.validation) ? parsed.validation : {};
const branchModel = typeof parsed.branchModel === 'object' && parsed.branchModel !== null && !Array.isArray(parsed.branchModel) ? parsed.branchModel : {};
const project = typeof parsed.project === 'object' && parsed.project !== null && !Array.isArray(parsed.project) ? parsed.project : {};
const fieldNames = typeof project.fieldNames === 'object' && project.fieldNames !== null && !Array.isArray(project.fieldNames) ? project.fieldNames : {};
const mergedLabels = { ...DEFAULT_LABELS, ...labels };
if (typeof mergedLabels.epic !== 'string' || !mergedLabels.epic.trim()) {
throw new Error(`Policy file ${resolvedPath} must define labels.epic as a non-empty string`);
}
return {
...DEFAULT_POLICY,
...parsed,
labels: mergedLabels,View on GitHub (pinned to 8321021c54)