affaan-m/ECC · error

Managed Claude install-state is invalid at

Error message

Managed Claude install-state is invalid at ${statePath}

What it means

validateManagedState() checks the shape of the managed Claude install-state file read from statePath. It requires a target object and arrays of non-empty-string selectedModules and operations; when that top-level shape fails it throws this error. This protects subsequent install/update logic from corrupted or hand-mangled state.

Solutions

  1. Inspect the state file at statePath and restore the required shape: an object with target (object), selectedModules (array of non-empty strings), and operations (array).
  2. Restore the file from version control/backup if it is tracked, or from a backup of your config directory.
  3. Delete the corrupted state file and re-run the install so ECC regenerates valid state.
  4. If you migrated from an older ECC version, re-run the installer to rewrite state in the current format.

Example fix

// before (state.json)
{ "target": "~/.claude", "selectedModules": "agents" }
// after
{ "target": { "configDir": "/home/me/.claude" }, "selectedModules": ["agents"], "operations": [] }
Defensive patterns

Strategy: validation

Validate before calling

const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));
const ok = state && typeof state === 'object'
  && typeof state.target === 'object' && state.target !== null && !Array.isArray(state.target)
  && Array.isArray(state.selectedModules)
  && state.selectedModules.every(m => typeof m === 'string' && m.length > 0)
  && Array.isArray(state.operations);
if (!ok) throw new Error(`State shape invalid before call: ${statePath}`);

Type guard

function hasValidStateShape(state) {
  return !!state && typeof state === 'object' && !Array.isArray(state)
    && typeof state.target === 'object' && state.target !== null && !Array.isArray(state.target)
    && Array.isArray(state.selectedModules)
    && state.selectedModules.every(m => typeof m === 'string' && m.length > 0)
    && Array.isArray(state.operations);
}

Try / catch

try {
  validateManagedState(statePath);
} catch (err) {
  if (err.message.startsWith('Managed Claude install-state is invalid')) {
    console.error(`${statePath} failed shape validation — restore or re-install`);
    process.exitCode = 1;
  } else throw err;
}

Prevention

When it happens

Trigger: A state file at statePath missing required fields (target, selectedModules, operations), with selectedModules containing non-string or empty-string entries, or with any of the three fields the wrong type (e.g. operations as an object); the file was truncated or manually edited.

Common situations: Manual cleanup of ~/.claude state deleting fields; interrupted install leaving a partially written state; an older ECC state format no longer matching the current validator; syncing dotfiles with a stale/different version of the state file.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/a83a8b2f86328adf. Report an issue: GitHub.

Appendix: source

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

      };
    }
  }
  return null;
}

function validateManagedState(state, statePath, expectedRoot) {
  const selectedModules = state?.resolution?.selectedModules;
  const operations = state?.operations;
  if (
    state?.schemaVersion !== 'ecc.install.v1'
    || !state.target
    || typeof state.target !== 'object'
    || Array.isArray(state.target)
    || !Array.isArray(selectedModules)
    || !selectedModules.every(moduleId => typeof moduleId === 'string' && moduleId.length > 0)
    || !Array.isArray(operations)
  ) {
    throw new Error(`Managed Claude install-state is invalid at ${statePath}`);
  }

  for (const operation of operations) {
    if (
      !operation
      || typeof operation !== 'object'
      || typeof operation.destinationPath !== 'string'
      || !path.isAbsolute(operation.destinationPath)
      || !isWithinRoot(operation.destinationPath, expectedRoot)
    ) {
      throw new Error(`Managed Claude install-state is invalid at ${statePath}`);
    }
  }

  return { selectedModules, operations };
}

function operationOverlapsPlugin(operation, expectedRoot) {

View on GitHub (pinned to 8321021c54)