affaan-m/ECC · error
Failed to read
Error message
Failed to read ${label}: ${error.message} What it means
readJson in scripts/lib/install-state.js wraps every failure of fs.readFileSync + JSON.parse of an install-state file (e.g. .claude/install-state.json) into a single uniform error. It conflates file-not-found, permission errors, and malformed JSON into one message, preserving the underlying Node error text.
Solutions
- Check the underlying error in the message: ENOENT means the file is missing (run the install once to create it)
- If the file exists, validate it with `node -e "JSON.parse(require('fs').readFileSync(path,'utf8'))"` and fix the syntax error
- Fix file permissions if the message shows EACCES
- If the state file is corrupt, delete it and re-run the installer to regenerate a fresh state
Example fix
// before: reading state from a script without guarding
const state = state();
// after
let state;
try { state = state(); } catch (e) {
if (/ENOENT/.test(e.message)) state = undefined; // first run, no state yet
else throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check before reading state
const statePath = '.claude/install-state.json';
const stateExists = fs.existsSync(statePath);
const stateReadable = stateExists && (() => { try { fs.accessSync(statePath, fs.constants.R_OK); return true; } catch { return false; } })();
let stateWellFormed = false;
if (stateReadable) { try { JSON.parse(fs.readFileSync(statePath, 'utf8')); stateWellFormed = true; } catch {} } Try / catch
try {
const state = readInstallState();
} catch (e) {
if (/Failed to read .*: ENOENT/.test(e.message)) {
// first run — treat as fresh install
} else if (/Failed to read .*: Unexpected token|JSON/.test(e.message)) {
// corrupt file — regenerate state
} else throw e;
} Prevention
- Never hand-edit the install-state file; regenerate it via the installer
- Treat a missing state file as a normal first-run condition, not a crash
- Validate any external tooling that touches the state file with JSON.parse before writing
- Check file permissions when installing in CI or shared environments
When it happens
Trigger: readInstallState/state is called and the state file is missing, unreadable (permissions), or contains invalid JSON — any readFileSync or JSON.parse throw is caught and re-thrown with the label prefixed.
Common situations: Running installer commands before the first install (state file does not exist yet); a crashed previous install left a truncated/partial state file; hand-editing the state JSON introduced a syntax error; restrictive file permissions after cloning on another machine.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- Failed to parse at
- Failed to parse at
- A managed install-state path is required before preflight.
- application request must be a JSON object
- bundle values must be finite JSON data
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/ae2106a2161df953.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/install-state.js:29
// bytes must be the installed bytes). install-state is validated by the
// hand-rolled validator below, which enforces the same constraints as
// schemas/install-state.schema.json (ecc.install.v1).
let cachedValidator = null;
function cloneJsonValue(value) {
if (value === undefined) {
return undefined;
}
return JSON.parse(JSON.stringify(value));
}
function readJson(filePath, label) {
try {
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
} catch (error) {
throw new Error(`Failed to read ${label}: ${error.message}`);
}
}
function getValidator() {
if (cachedValidator) {
return cachedValidator;
}
cachedValidator = createFallbackValidator();
return cachedValidator;
}
function createFallbackValidator() {
const validate = state => {
const errors = [];
validate.errors = errors;
function pushError(instancePath, message) {View on GitHub (pinned to 8321021c54)