affaan-m/ECC · error
Invalid at : expected a JSON object
Error message
Invalid ${label} at ${filePath}: expected a JSON object What it means
After successfully parsing the file, readJsonObject in the Cursor project target additionally requires the top-level value to be a plain JSON object — not null, not an array. Config files this installer merges into must be objects so keys can be merged; anything else is rejected with the file path in the message.
Solutions
- Open the file at filePath in the message and change the top-level value to a JSON object `{ ... }`
- If the file is an empty placeholder, replace `[]` or `null` with `{}`
- Re-run the install so the merge operation can apply on the now-object-shaped file
Example fix
// before
[]
// after
{} Defensive patterns
Strategy: type-guard
Validate before calling
// Pre-check the root shape before install
const parsed = JSON.parse(fs.readFileSync(cursorConfigPath, 'utf8'));
if (parsed === null || Array.isArray(parsed) || typeof parsed !== 'object') {
console.error(`${cursorConfigPath} must be a JSON object at the top level`);
} Type guard
function isJsonObject(v) {
return v !== null && typeof v === 'object' && !Array.isArray(v);
} Try / catch
try {
runInstallOperation(op);
} catch (e) {
if (/Invalid .* at .*: expected a JSON object/.test(e.message)) {
// rewrite the file's root as an object and retry
} else throw e;
} Prevention
- Never replace object-shaped config files with arrays or null placeholders
- Use `{}` as the empty-state file content, not `[]` or `null`
- Validate file root shape with a type guard before invoking merge operations
When it happens
Trigger: createJsonMergeOperation reads a destination file whose contents parse as JSON but whose root is an array (e.g. `[]` or `[...]`), a bare string/number, or the literal `null`.
Common situations: Someone reset a Cursor config file to `[]` assuming it is a list format; a tool exported settings as a JSON array; a script wrote `null` as a placeholder.
Related errors
- Failed to parse at
- Invalid at : expected a JSON object
- Failed to parse at
- Invalid at : expected a JSON object
- Invalid at : expected a JSON object
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/3dce563a1ccb6498.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install-targets/cursor-project.js:32
if (path.basename(sourceRelativeFile).toLowerCase() === 'readme.md') {
return null;
}
return fileName.endsWith('.md')
? `${fileName.slice(0, -3)}.mdc`
: fileName;
}
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 createJsonMergeOperation({ moduleId, repoRoot, sourceRelativePath, destinationPath }) {
const sourcePath = path.join(repoRoot, sourceRelativePath);
if (!fs.existsSync(sourcePath) || !fs.statSync(sourcePath).isFile()) {
return null;
}
return createManagedOperation({
kind: 'merge-json',
moduleId,
sourceRelativePath,
destinationPath,
strategy: 'merge-json',
ownership: 'managed',View on GitHub (pinned to 8321021c54)