affaan-m/ECC · error · Error
Failed to parse ${label} at ${filePath}: ${error.message}
Error message
Failed to parse ${label} at ${filePath}: ${error.message} What it means
Thrown by readJsonObject in scripts/lib/install-targets/kimi-project.js when JSON.parse fails on the file at filePath. In the Kimi adapter this is called on <repoRoot>/.mcp.json (label is the sourceRelativePath '.mcp.json') inside createMcpMergeOperation, which runs during planOperations whenever a module exposes the 'mcp-configs' path. The original parse error message is inlined so the caller sees the exact JSON syntax problem.
Source
Thrown at scripts/lib/install-targets/kimi-project.js:15
const fs = require('fs');
const path = require('path');
const {
createInstallTargetAdapter,
createManagedOperation,
isForeignPlatformPath,
} = require('./helpers');
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 createMcpMergeOperation(moduleId, repoRoot, targetRoot) {
if (!repoRoot) {
throw new Error('repoRoot is required to plan Kimi MCP configuration');
}
const sourceRelativePath = '.mcp.json';
const sourcePath = path.join(repoRoot, sourceRelativePath);
if (!fs.existsSync(sourcePath) || !fs.statSync(sourcePath).isFile()) {
return null;View on GitHub (pinned to 01e15490f0)
Solutions
- Open the file at filePath (the message includes the absolute path) and run node -e "JSON.parse(require('fs').readFileSync(process.argv[1],'utf8'))" <filePath> to surface the exact position.
- Fix the JSON syntax error (most commonly a trailing comma, missing quote, or single quotes instead of double).
- Strip a leading BOM: sed -i '1s/^\xEF\xBB\xBF//' <filePath>.
- Validate with jq empty <filePath> or npx jsonlint <filePath> before retrying the install.
Example fix
// before (<repoRoot>/.mcp.json)
{
"mcpServers": {
"context7": { "command": "npx", },
}
}
// after
{
"mcpServers": {
"context7": { "command": "npx" }
}
} Defensive patterns
Strategy: try-catch
Validate before calling
function preflightJsonObject(filePath) {
const raw = require('fs').readFileSync(filePath, 'utf8').replace(/^\uFEFF/, '');
const v = JSON.parse(raw); // throws on bad JSON
if (!v || typeof v !== 'object' || Array.isArray(v)) {
throw new Error(`${filePath} top level must be a JSON object`);
}
return v;
}
// before planning the Kimi install:
const mcpPath = path.join(repoRoot, '.mcp.json');
if (fs.existsSync(mcpPath)) preflightJsonObject(mcpPath); Type guard
function isJsonObject(value) {
return value !== null && typeof value === 'object' && !Array.isArray(value);
} Try / catch
try {
planInstallTargetScaffold({ target: 'kimi', modules, repoRoot, projectRoot });
} catch (err) {
if (/Failed to parse .*\.mcp\.json/.test(err.message)) {
console.error('Source .mcp.json is corrupt. Fix JSON syntax and retry. Detail:', err.message);
process.exit(1);
}
throw err;
} Prevention
- Add a CI step that runs jq empty .mcp.json on every commit.
- Lint the file in your editor with a JSON schema.
- Configure your editor to write plain UTF-8 (no BOM).
When it happens
Trigger: Planning or applying a Kimi install (target: 'kimi') when the source repo's <repoRoot>/.mcp.json exists but is not valid JSON — trailing comma, unterminated string, single quotes, UTF-8 BOM, or a partially written file.
Common situations: Hand-edited .mcp.json with a syntax error; another tool mid-write when ECC read it; copy-paste introduced a trailing comma; editor saved with a BOM; JSONL content mistakenly placed in a .json file.
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
- Invalid ${label} at ${filePath}: expected a JSON object
- repoRoot is required to plan Kimi MCP configuration
- Failed to parse ${label} at ${filePath}: ${error.message}
- Cannot merge ECC configuration into invalid JSON at ${destin
- Kimi requires an explicit --profile choice in this mode.
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/bda414a353367c2e.
Report an issue: GitHub.