affaan-m/ECC · error · Error
Failed to load policy from ${resolvedPath}: ${error.message}
Error message
Failed to load policy from ${resolvedPath}: ${error.message} What it means
Thrown by loadPolicy() in scripts/lib/github-coordination/policy.js when the coordination policy file exists at the resolved path but cannot be read or parsed as JSON. The error wraps the underlying readFileSync/JSON.parse failure so the caller knows which file broke and why.
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 : {};
return {
...DEFAULT_POLICY,
...parsed,
labels: { ...DEFAULT_LABELS, ...labels },
review: { ...DEFAULT_POLICY.review, ...review },
validation: { ...DEFAULT_POLICY.validation, ...validation },
branchModel: { ...DEFAULT_POLICY.branchModel, ...branchModel },
project: {View on GitHub (pinned to 01e15490f0)
Solutions
- Validate the file with a JSON linter: node -e "JSON.parse(require('fs').readFileSync('config/github-native-coordination.json','utf8'))" and fix the reported syntax error.
- Confirm the path is a regular file: ls -l <resolvedPath> and ensure it is not a directory or broken symlink.
- Check read permissions: chmod +r <resolvedPath> or run the command as a user with access.
- If you do not need a custom policy, delete or rename the file; loadPolicy returns DEFAULT_POLICY when the file is absent.
Example fix
// before: config/github-native-coordination.json contains { labels: { epic: "epic" } } (unquoted-ish / trailing comma)
// after:
{
"labels": { "epic": "epic" }
} Defensive patterns
Strategy: try-catch
Validate before calling
const fs = require('fs');
function canLoadPolicy(p) {
if (!fs.existsSync(p)) return true; // absent is OK
try { JSON.parse(fs.readFileSync(p, 'utf8')); return true; }
catch { return false; }
}
if (!canLoadPolicy(resolvedPath)) {
console.error(`${resolvedPath} is not valid JSON; using defaults`);
} Try / catch
let policy;
try {
policy = loadPolicy(rootDir, configPath);
} catch (err) {
if (/Failed to load policy/.test(err.message)) {
console.warn(`${err.message} — falling back to DEFAULT_POLICY`);
policy = require('./policy').DEFAULT_POLICY;
} else {
throw err;
}
} Prevention
- Lint the policy file in pre-commit hooks using a JSON validator.
- Treat config/github-native-coordination.json as code: review diffs before merge.
- Document the schema (e.g. with a JSON Schema file) and validate on save.
- Run the ECC test suite after editing the policy file.
When it happens
Trigger: loadPolicy(rootDir, configPath) is called, fs.existsSync(resolvedPath) returns true, then either fs.readFileSync throws (permissions, EISDIR, EACCES) or JSON.parse throws (trailing comma, unquoted keys, BOM, truncated file).
Common situations: Hand-edited config/github-native-coordination.json with a syntax error; file saved with a leading BOM or CRLF inside a string; file replaced by a directory or symlink to a missing target; permissions locked down so Node cannot read it.
Related errors
- gh ${args.join(' ')} returned invalid JSON: ${error.message}
- Malformed coordination JSON in body: ${error.message} — raw:
- Policy file ${resolvedPath} must contain a JSON object, got
- parse config %s: %w
- invalid repo: expected non-empty string, got ${JSON.stringif
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/8e8b99756ed45d84.
Report an issue: GitHub.