{"record":{"id":"ae2106a2161df953","repo":"affaan-m/ECC","slug":"failed-to-read-label-error-message-ae2106","errorCode":null,"errorMessage":"Failed to read ${label}: ${error.message}","messagePattern":"Failed to read (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/install-state.js","lineNumber":24,"sourceCode":"// bytes must be the installed bytes). install-state is validated by the\n// hand-rolled validator below, which enforces the same constraints as\n// schemas/install-state.schema.json (ecc.install.v1).\n\nlet cachedValidator = null;\n\nfunction cloneJsonValue(value) {\n  if (value === undefined) {\n    return undefined;\n  }\n\n  return JSON.parse(JSON.stringify(value));\n}\n\nfunction readJson(filePath, label) {\n  try {\n    return JSON.parse(fs.readFileSync(filePath, 'utf8'));\n  } catch (error) {\n    throw new Error(`Failed to read ${label}: ${error.message}`);\n  }\n}\n\nfunction getValidator() {\n  if (cachedValidator) {\n    return cachedValidator;\n  }\n\n  cachedValidator = createFallbackValidator();\n  return cachedValidator;\n}\n\nfunction createFallbackValidator() {\n  const validate = state => {\n    const errors = [];\n    validate.errors = errors;\n\n    function pushError(instancePath, message) {","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/install-state.js#L6-L42","documentation":"Thrown by readJson() in install-state.js when either fs.readFileSync throws (file missing, permission denied) or JSON.parse throws (malformed JSON). The label argument identifies which file was being read so the message is actionable. install-state.js is intentionally dependency-free, so the error wraps the underlying node error message verbatim.","triggerScenarios":"Reading the install-state file (ecc-install-state.json) before it was ever written; reading after a partial write corrupted the JSON; insufficient filesystem permissions; the path resolved to a directory.","commonSituations":"First run after install before any state exists; a concurrent process truncated the file; an OS crash mid-write left invalid JSON; permissions changed under .claude/ or .cursor/.","solutions":["Check whether the path exists with fs.existsSync before reading; treat absence as 'not installed'.","If the file is corrupt, delete it and let the installer recreate it on next run.","Verify read permissions on the parent directory (ls -la).","Ensure no other tool writes to ecc-install-state.json with a different schema."],"exampleFix":"// before\nconst state = readJson(statePath, 'install-state');\n// after\nif (!fs.existsSync(statePath)) return null;\nlet state;\ntry { state = readJson(statePath, 'install-state'); }\ncatch (e) {\n  fs.rmSync(statePath, { force: true }); // corrupt — let installer rewrite\n  return null;\n}","handlingStrategy":"try-catch","validationCode":"if (!fs.existsSync(filePath)) {\n  return null; // no prior state — fresh install\n}\nconst stat = fs.statSync(filePath);\nif (!stat.isFile()) {\n  throw new Error(`${filePath} is not a regular file`);\n}\n// proceed to readJson","typeGuard":null,"tryCatchPattern":"try {\n  return readJson(filePath, label);\n} catch (err) {\n  if (/Failed to read/.test(err.message)) {\n    // corrupt or unreadable — back up and reset\n    fs.rmSync(filePath, { force: true });\n    return null;\n  }\n  throw err;\n}","preventionTips":["Treat a missing install-state file as 'not installed' rather than an error.","Use atomic writes (the project's atomic-write.js) when writing install-state to avoid partial-JSON corruption."],"tags":["install-state","io","json","filesystem"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}