affaan-m/ECC · error · Error

${label} is invalid at ${filePath}: ${error.message}

Error message

${label} is invalid at ${filePath}: ${error.message}

What it means

Thrown by readJsonObject in scripts/lib/install/inventory.js when JSON.parse fails. The helper is called in findManagedClaudeInstalls with label 'Managed Claude install-state' on either <configDir>/ecc/install-state.json or <projectRoot>/.claude/ecc/install-state.json. The original parse error is inlined.

Source

Thrown at scripts/lib/install/inventory.js:36

    || os.homedir();
  const configDir = options.configDir
    || process.env.CLAUDE_CONFIG_DIR
    || path.join(homeDir, '.claude');
  const projectRoot = options.projectRoot || process.cwd();

  return {
    homeDir: path.resolve(homeDir),
    configDir: path.resolve(configDir),
    projectRoot: path.resolve(projectRoot),
  };
}

function readJsonObject(filePath, label) {
  let value;
  try {
    value = JSON.parse(fs.readFileSync(filePath, 'utf8'));
  } catch (error) {
    throw new Error(`${label} is invalid at ${filePath}: ${error.message}`);
  }
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
    throw new Error(`${label} is invalid at ${filePath}: expected a JSON object`);
  }
  return value;
}

function findManualClaudePlugin(options = {}) {
  const { configDir } = resolveClaudePaths(options);
  const pluginsDir = path.join(configDir, 'plugins');
  const candidates = [
    ['ecc', '.claude-plugin', 'plugin.json'],
    ['ecc', 'plugin.json'],
    ['ecc@ecc', '.claude-plugin', 'plugin.json'],
    ['ecc@ecc', 'plugin.json'],
    ['everything-claude-code', '.claude-plugin', 'plugin.json'],
    ['everything-claude-code', 'plugin.json'],
  ];

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Open the named install-state.json and run jq empty <file> to find the parse error.
  2. If unrecoverable, back it up and delete it — ECC will treat the install as unmanaged and you can reinstall cleanly.
  3. Re-run the ECC inventory command to confirm the state is regenerated.
  4. Audit why the file became corrupt (interrupted process, concurrent writers) before retrying.

Example fix

# before
$ jq empty ~/.claude/ecc/install-state.json
parse error: ...

# after
mv ~/.claude/ecc/install-state.json ~/.claude/ecc/install-state.json.bak
# re-run the install / inventory command
Defensive patterns

Strategy: try-catch

Validate before calling

function safeReadState(p) {
  try { return JSON.parse(fs.readFileSync(p, 'utf8')); }
  catch (e) { return null; }
}
const state = safeReadState(statePath);
if (!state) {
  console.warn(`Unreadable state at ${statePath} — ECC will treat the install as unmanaged.`);
}

Type guard

function isJsonObject(v) {
  return v !== null && typeof v === 'object' && !Array.isArray(v);
}

Try / catch

try {
  findManagedClaudeInstalls();
} catch (err) {
  if (/install-state is invalid at/.test(err.message)) {
    console.error('Corrupt install-state — back up and remove, then reinstall.');
  }
  throw err;
}

Prevention

When it happens

Trigger: Running the inventory/repair flow when an existing ECC install-state.json is corrupt JSON — usually from an interrupted install, manual edit, or disk issue.

Common situations: A previous install was killed mid-write; a tool manually edited install-state.json; disk corruption; a partial state left by a crashed upgrade.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/ee156496952b0621. Report an issue: GitHub.