{"record":{"id":"da1937228389d17c","repo":"affaan-m/ECC","slug":"invalid-json-in-label-at-filepath-error-message","errorCode":null,"errorMessage":"Invalid JSON in ${label} at ${filePath}: ${error.message}","messagePattern":"Invalid JSON in (.+?) at (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/hooks-config.js","lineNumber":39,"sourceCode":"\nconst HOOKS_FILENAME = 'hooks.json';\nconst METADATA_FILENAME = 'hooks.metadata.json';\nconst FINGERPRINT_LENGTH = 12;\nconst FINGERPRINT_PATTERN = /^[0-9a-f]{12}$/;\n\nfunction readJsonObject(filePath, label) {\n  let raw;\n  try {\n    raw = fs.readFileSync(filePath, 'utf8');\n  } catch (error) {\n    throw new Error(`Unable to read ${label} at ${filePath}: ${error.message}`);\n  }\n\n  let parsed;\n  try {\n    parsed = JSON.parse(raw);\n  } catch (error) {\n    throw new Error(`Invalid JSON in ${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 metadataPathFor(hooksPath) {\n  return path.join(path.dirname(hooksPath), METADATA_FILENAME);\n}\n\n/**\n * JSON.stringify with object keys sorted, so a fingerprint does not change when\n * someone reorders the keys inside a hook object.\n */\nfunction stableStringify(value) {","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/hooks-config.js#L21-L57","documentation":"readJsonObject() parses the file contents with JSON.parse; if parsing fails it throws 'Invalid JSON in <label> at <filePath>: <reason>'. The library requires strict, well-formed JSON (no comments, no trailing commas, no JS syntax) for hooks settings and metadata sidecar files, and surfaces the parser's message with the file location.","triggerScenarios":"Any caller (hooksConfig, readHooksConfig, addJsonMergeOperation) reading a file whose content is not valid JSON — hand-edited settings with a trailing comma or comment, truncated write, merge-conflict markers (<<<<<<<) left in the file, or a JSON5/JSONC file passed where strict JSON is expected.","commonSituations":"Manual edits to .claude/settings.json or hooks.json introducing syntax errors; git merge conflicts resolved but markers forgotten; editor saved with comments in a .json file; partial disk write leaving truncated JSON.","solutions":["Open the file at <filePath> and fix the JSON at the position given in error.message (JSON.parse messages cite line/column).","Remove non-JSON constructs: comments, trailing commas, single quotes, merge-conflict markers.","If the file came from a merge, re-merge properly or restore from git and re-apply changes as valid JSON.","Validate with `node -e \"JSON.parse(require('fs').readFileSync('<filePath>','utf8'))\"` before rerunning."],"exampleFix":"// before (.claude/settings.json)\n{ \"hooks\": { \"Stop\": [] }, } // trailing comma -> Invalid JSON\n// after\n{ \"hooks\": { \"Stop\": [] } }","handlingStrategy":"try-catch","validationCode":"const fs = require('fs');\nfunction isParsableJson(p) {\n  try { JSON.parse(fs.readFileSync(p, 'utf8')); return true; } catch (e) { return false; }\n}\nif (!isParsableJson('.claude/settings.json')) {\n  console.error('settings.json is not valid JSON; fix it before running hooks tooling');\n}","typeGuard":"function isJsonObjectText(text) { try { const v = JSON.parse(text); return v !== null && typeof v === 'object' && !Array.isArray(v); } catch { return false; } }","tryCatchPattern":"try {\n  const cfg = readHooksConfig(path);\n} catch (err) {\n  if (String(err.message).startsWith('Invalid JSON in')) {\n    console.error(`${err.message}\\nTip: JSON.parse messages cite line/column; remove comments and trailing commas.`);\n    // optionally back up and reset: fs.copyFileSync(path, path + '.bak'); fs.writeFileSync(path, '{}');\n  } else throw err;\n}","preventionTips":["Never put comments or trailing commas in .json files — use a .jsonc-aware editor warning or a JSON linter.","Run `node -e \"JSON.parse(require('fs').readFileSync(f,'utf8'))\"` as a pre-commit check on config files.","Resolve merge conflicts fully; grep for conflict markers before committing configs.","Avoid hand-editing generated config files; use the ECC tooling."],"tags":["json","parse-error","config","hooks"],"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"}