{"record":{"id":"cface571f034809a","repo":"affaan-m/ECC","slug":"failed-to-parse-label-at-filepath-error-message","errorCode":null,"errorMessage":"Failed to parse ${label} at ${filePath}: ${error.message}","messagePattern":"Failed to parse (.+?) at (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/install/plan.js","lineNumber":124,"sourceCode":"  return {\n    kind: 'copy-file',\n    moduleId,\n    sourcePath,\n    sourceRelativePath,\n    destinationPath,\n    strategy,\n    ownership: 'managed',\n    scaffoldOnly: false,\n    ...(contentTransform ? { contentTransform } : {}),\n  };\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 materializeClaudeSettingsOperation(sourceRoot, operation) {\n  const sourcePath = path.join(sourceRoot, operation.sourceRelativePath);\n  if (!fs.existsSync(sourcePath)) {\n    return [];\n  }\n\n  // Stable ids and descriptions live in hooks/hooks.metadata.json; readHooksConfig\n  // merges them back so managed settings entries keep their ids.\n  const hooksConfig = readHooksConfig(sourcePath, operation.sourceRelativePath);","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/install/plan.js#L106-L142","documentation":"readJsonObject reads a JSON file from disk and parses it. If fs.readFileSync succeeds but JSON.parse fails (malformed JSON, trailing commas, comments, truncated file, wrong encoding), the parse error is wrapped in this error naming the label and file path plus the underlying parse message. It separates parse failures from shape failures (error 364).","triggerScenarios":"Calling readJsonObject(filePath, label) — e.g. materializeScaffoldOperation reading a scaffold/manifest JSON — when the file content is not valid JSON: syntax errors, BOM/encoding issues, truncated writes, or the file being HTML/error output instead of JSON.","commonSituations":"Hand-editing a scaffold or settings JSON and leaving a trailing comma or comment; a partial write from a crashed process; downloading a 404 HTML page saved as .json; smart quotes introduced by a rich-text editor.","solutions":["Fix the JSON syntax in the file at filePath — validate it with a JSON linter or `JSON.parse` in a REPL; the wrapped message names the exact parse offset.","Restore the file from version control or regenerate it with the scaffolder.","Check for a UTF-8 BOM or wrong encoding; re-save the file as plain UTF-8.","If the file was truncated by a crashed process, rerun the generator to rewrite it."],"exampleFix":"// before: settings.json with trailing comma\n{ \"locale\": \"en\", }\n\n// after\n{ \"locale\": \"en\" }","handlingStrategy":"validation","validationCode":"function isParseableJsonObject(p) {\n  try { JSON.parse(fs.readFileSync(p, 'utf8').replace(/^\\uFEFF/, '')); return true; }\n  catch { return false; }\n}","typeGuard":"function parsesAsObject(text) {\n  try { const v = JSON.parse(text); return v !== null && typeof v === 'object' && !Array.isArray(v); }\n  catch { return false; }\n}","tryCatchPattern":"try {\n  const cfg = readJsonObject(path, 'scaffold config');\n} catch (e) {\n  if (e.message.startsWith('Failed to parse')) {\n    console.error(`Malformed JSON in ${path}; validate with a JSON linter and fix syntax.`);\n    return restoreFromVcs(path);\n  }\n  throw e;\n}","preventionTips":["Validate JSON files with a linter before committing them as configs.","Never hand-edit generated JSON without re-validating (watch for trailing commas/comments).","Save config files as plain UTF-8 without BOM; avoid rich-text editors.","Restore from version control rather than fixing truncated files by hand."],"tags":["json","parse-error","configuration"],"backgroundTag":"json-parse-error","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}