{"record":{"id":"1b388352e06839b5","repo":"affaan-m/ECC","slug":"failed-to-parse-label-at-filepath-error-m","errorCode":null,"errorMessage":"Failed to parse ${label} at ${filePath}: ${error.message}","messagePattern":"Failed to parse (.+?) at (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/install-executor.js","lineNumber":211,"sourceCode":"  operations.push(\n    buildCopyFileOperation({\n      moduleId: options.moduleId,\n      sourcePath,\n      sourceRelativePath: options.sourceRelativePath,\n      destinationPath: options.destinationPath,\n      strategy: options.strategy || 'preserve-relative-path'\n    })\n  );\n\n  return true;\n}\n\nfunction readJsonObject(filePath, label) {\n  let parsed;\n  try {\n    parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));\n  } catch (error) {\n    throw new Error(`Failed to parse ${label} at ${filePath}: ${error.message}`);\n  }\n\n  if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n    throw new Error(`Invalid ${label} at ${filePath}: expected a JSON object`);\n  }\n\n  return parsed;\n}\n\nfunction addCursorAgentDataScaffoldOperations(operations, options) {\n  const scaffoldRoot = path.join(options.sourceRoot, 'scaffolds', 'cursor');\n  if (!fs.existsSync(scaffoldRoot)) {\n    return;\n  }\n\n  addFileCopyOperation(operations, {\n    moduleId: options.moduleId,\n    sourceRoot: options.sourceRoot,","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/affaan-m/ECC/blob/06c5e118c4d3e6c3b7f9445f973a2194c82de193/scripts/lib/install-executor.js#L193-L229","documentation":"readJsonObject() wraps JSON.parse(fs.readFileSync(...)) for JSON files used as merge payloads during install (hooks config, MCP config, cursor/kimi project scaffolds). When the file exists but is not parseable JSON, the underlying SyntaxError is rethrown with this message, including the file path and the parser's reason.","triggerScenarios":"A merge-json source file containing a trailing comma, unquoted key, JSONC-style comment, or truncated content; a BOM-prefixed file; an empty file handed to JSON.parse.","commonSituations":"Hand-editing hooks.json or an .mcp.json-style config and leaving a trailing comma; files mangled by git merge conflicts; editors saving comments into .json files.","solutions":["Reproduce the exact parser error: node -e \"JSON.parse(require('fs').readFileSync('<file>','utf8'))\" or jq . <file>","Fix the reported offset - remove trailing commas/comments, close unbalanced braces","If the file is repo-managed, restore it: git checkout -- <file>"],"exampleFix":"// before (hooks config with trailing comma)\n{ \"hooks\": { \"PreToolUse\": [] }, }\n\n// after\n{ \"hooks\": { \"PreToolUse\": [] } }","handlingStrategy":"validation","validationCode":"function assertValidJsonFile(filePath) {\n  const text = fs.readFileSync(filePath, 'utf8').replace(/^\\uFEFF/, ''); // strip BOM\n  JSON.parse(text); // throws a SyntaxError with the exact offset before the installer runs\n}\n\nfor (const payloadPath of collectMergePayloadFiles()) {\n  assertValidJsonFile(payloadPath);\n}","typeGuard":null,"tryCatchPattern":"try {\n  resolveInstallPlan(options);\n} catch (error) {\n  if (/^Failed to parse .*: /.test(error.message)) {\n    // error.message names the payload file and parser reason; fix that file, then re-run\n  } else {\n    throw error;\n  }\n}","preventionTips":["Lint every JSON payload in CI (jq . file.json or a JSON.parse check)","Never put comments, trailing commas, or JSONC syntax in merge-payload files","Prefer machine-generated configs over hand-edited ones for merge sources"],"tags":["installer","json","config-parsing","merge-payload"],"backgroundTag":"json-parse-error","analyzedSha":"06c5e118c4d3e6c3b7f9445f973a2194c82de193","analyzedAt":"2026-08-18T11:27:13.915Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}