affaan-m/ECC · error · Error
Invalid JSON in ${label}: ${error.message}
Error message
Invalid JSON in ${label}: ${error.message} What it means
The readJson() helper in validate-install-manifests.js wraps JSON.parse(fs.readFileSync(...)) in a try-catch and rethrows with a labeled message. The label identifies which manifest or schema file failed (e.g. 'modules manifest', 'profiles schema'). This error fires when the file exists but contains invalid JSON syntax — trailing commas, unquoted keys, single quotes, comments, or truncated content.
Source
Thrown at scripts/ci/validate-install-manifests.js:36
const COMPONENTS_SCHEMA_PATH = path.join(REPO_ROOT, 'schemas/install-components.schema.json');
const CURATED_SKILLS_DIR = path.join(REPO_ROOT, 'skills');
// Empty by default; add only curated skills that are intentionally unshipped.
const INTENTIONALLY_UNSHIPPED_SKILL_IDS = new Set([
'skill-comply', // meta/measurement dev-skill; ships committed .pyc artifacts and a nested .gitignore, revisit after packaging cleanup
]);
const COMPONENT_FAMILY_PREFIXES = {
baseline: 'baseline:',
language: 'lang:',
framework: 'framework:',
capability: 'capability:',
locale: 'locale:',
};
function readJson(filePath, label) {
try {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
} catch (error) {
throw new Error(`Invalid JSON in ${label}: ${error.message}`);
}
}
function normalizeRelativePath(relativePath) {
return String(relativePath).replace(/\\/g, '/').replace(/\/+$/, '');
}
function isCuratedSkillReferenced(claimedPaths, skillId) {
const skillRoot = `skills/${skillId}`;
for (const claimedPath of claimedPaths.keys()) {
if (claimedPath === skillRoot || claimedPath.startsWith(`${skillRoot}/`)) {
return true;
}
}
return false;
}View on GitHub (pinned to 01e15490f0)
Solutions
- Run the JSON file through a linter or `node -e "JSON.parse(require('fs').readFileSync('<path>','utf8'))"` to locate the exact syntax error
- Check for trailing commas, unquoted keys, single-quoted strings, or comments — none are valid JSON
- If a merge conflict occurred, ensure all conflict markers (<<<<<<<, =======, >>>>>>>) are removed
- Validate against the schema file to confirm structural correctness after fixing syntax
Example fix
// before — manifest contains a trailing comma
{
"modules": [
{ "id": "foo" },
]
}
// after
{
"modules": [
{ "id": "foo" }
]
} Defensive patterns
Strategy: try-catch
Validate before calling
// Validate JSON files before running the manifest validator
const fs = require('fs');
const files = [
'manifests/install-modules.json',
'manifests/install-profiles.json',
'manifests/install-components.json',
];
for (const file of files) {
try {
JSON.parse(fs.readFileSync(file, 'utf8'));
console.log(`OK: ${file}`);
} catch (e) {
console.error(`INVALID: ${file} — ${e.message}`);
process.exit(1);
}
} Try / catch
// Catch the readJson error and report which file is broken
try {
validateInstallManifests();
} catch (error) {
if (error.message.startsWith('Invalid JSON in')) {
console.error('A manifest or schema file has invalid JSON.');
console.error(error.message);
console.error('Run: npx jsonlint <file> to find the syntax error.');
process.exit(1);
}
throw error;
} Prevention
- Use a JSON-aware editor or linter (jsonlint, prettier) when editing manifest files
- Never add comments or trailing commas to .json files — JSON does not support them
- After resolving git merge conflicts in JSON files, validate with `node -e "JSON.parse(require('fs').readFileSync('file','utf8'))"`
- Run the validator locally before pushing to CI
When it happens
Trigger: Running validate-install-manifests.js when manifests/install-modules.json, manifests/install-profiles.json, manifests/install-components.json, or their corresponding schema files contain malformed JSON. This is common after hand-editing a manifest or after a merge conflict leaves conflict markers in the file.
Common situations: Manual edits to install manifest JSON files that introduce syntax errors; git merge conflicts resolved incompletely leaving >>>>>>> markers; JSON5-style comments or trailing commas accidentally introduced; file truncated by an interrupted write or CI checkout issue.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- ${source} is missing the catalog count description
- ${source} is not valid JSON: ${error.message}
- Policy file ${resolvedPath} must contain a JSON object, got
- Invalid ${label} at ${filePath}: expected a JSON object
- Invalid install-state${label ? ` (${label})` : ''}: ${format
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/8d38189264457a82.
Report an issue: GitHub.