affaan-m/ECC · error · Error
Invalid at : expected a JSON object
Error message
Invalid ${label} at ${filePath}: expected a JSON object What it means
After a successful JSON.parse in readJsonObject(), the top-level value must be a plain JSON object. This error fires when the parsed root is anything else - an array, string, number, boolean or null - because downstream merge operations (deepMergeJson) need an object root to merge into.
Solutions
- Make the top-level value an object: wrap the array under a named key
- Compare against the object shape in ECC's shipped example configs
- Re-run the install after fixing; the merge will then apply key-by-key
Example fix
// before (top-level array)
[ { "matcher": "Bash" } ]
// after
{ "hooks": { "PreToolUse": [ { "matcher": "Bash" } ] } } Defensive patterns
Strategy: validation
Validate before calling
const value = JSON.parse(fs.readFileSync(payloadPath, 'utf8'));
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
throw new Error(`${payloadPath}: top-level value must be a JSON object`);
} Type guard
function isJsonObject(value) {
return value !== null && typeof value === 'object' && !Array.isArray(value);
} Try / catch
try {
resolveInstallPlan(options);
} catch (error) {
if (/expected a JSON object/.test(error.message)) {
// the named file parses but has a non-object root; wrap arrays under a key
} else {
throw error;
}
} Prevention
- Model payload files with a JSON schema (e.g. ajv) and validate before install
- Copy structural shapes from ECC's shipped example configs instead of inventing list forms
When it happens
Trigger: A hooks/MCP config whose top level is a JSON array (e.g. a bare list of servers); a payload file containing just a quoted string or a number; a file containing null.
Common situations: Users replacing an object-shaped config with a list; scaffolding or examples that emit arrays; misunderstanding of the expected config schema.
Related errors
- Failed to parse at
- Missing merge payload for
- Another ECC process is updating Claude settings
- application request must be a JSON object
- At least one guided harness must be selected
AI-assisted analysis of affaan-m/ECC@06c5e118c4 (2026-08-18).
Data as JSON: /api/errors/91ddf37dfa22351f.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install-executor.js:215
sourceRelativePath: options.sourceRelativePath,
destinationPath: options.destinationPath,
strategy: options.strategy || 'preserve-relative-path'
})
);
return true;
}
function readJsonObject(filePath, label) {
let parsed;
try {
parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
} catch (error) {
throw new Error(`Failed to parse ${label} at ${filePath}: ${error.message}`);
}
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
throw new Error(`Invalid ${label} at ${filePath}: expected a JSON object`);
}
return parsed;
}
function addCursorAgentDataScaffoldOperations(operations, options) {
const scaffoldRoot = path.join(options.sourceRoot, 'scaffolds', 'cursor');
if (!fs.existsSync(scaffoldRoot)) {
return;
}
addFileCopyOperation(operations, {
moduleId: options.moduleId,
sourceRoot: options.sourceRoot,
sourceRelativePath: path.join('scaffolds', 'cursor', 'ecc-agent-data.json'),
destinationPath: path.join(options.targetRoot, 'ecc-agent-data.json'),
strategy: 'preserve-relative-path'
});View on GitHub (pinned to 06c5e118c4)