{"record":{"id":"a83a8b2f86328adf","repo":"affaan-m/ECC","slug":"managed-claude-install-state-is-invalid-at-state","errorCode":null,"errorMessage":"Managed Claude install-state is invalid at ${statePath}","messagePattern":"Managed Claude install-state is invalid at (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/install/inventory.js","lineNumber":80,"sourceCode":"      };\n    }\n  }\n  return null;\n}\n\nfunction validateManagedState(state, statePath, expectedRoot) {\n  const selectedModules = state?.resolution?.selectedModules;\n  const operations = state?.operations;\n  if (\n    state?.schemaVersion !== 'ecc.install.v1'\n    || !state.target\n    || typeof state.target !== 'object'\n    || Array.isArray(state.target)\n    || !Array.isArray(selectedModules)\n    || !selectedModules.every(moduleId => typeof moduleId === 'string' && moduleId.length > 0)\n    || !Array.isArray(operations)\n  ) {\n    throw new Error(`Managed Claude install-state is invalid at ${statePath}`);\n  }\n\n  for (const operation of operations) {\n    if (\n      !operation\n      || typeof operation !== 'object'\n      || typeof operation.destinationPath !== 'string'\n      || !path.isAbsolute(operation.destinationPath)\n      || !isWithinRoot(operation.destinationPath, expectedRoot)\n    ) {\n      throw new Error(`Managed Claude install-state is invalid at ${statePath}`);\n    }\n  }\n\n  return { selectedModules, operations };\n}\n\nfunction operationOverlapsPlugin(operation, expectedRoot) {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/install/inventory.js#L62-L98","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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).","Restore the file from version control/backup if it is tracked, or from a backup of your config directory.","Delete the corrupted state file and re-run the install so ECC regenerates valid state.","If you migrated from an older ECC version, re-run the installer to rewrite state in the current format."],"exampleFix":"// before (state.json)\n{ \"target\": \"~/.claude\", \"selectedModules\": \"agents\" }\n// after\n{ \"target\": { \"configDir\": \"/home/me/.claude\" }, \"selectedModules\": [\"agents\"], \"operations\": [] }","handlingStrategy":"validation","validationCode":"const state = JSON.parse(fs.readFileSync(statePath, 'utf8'));\nconst ok = state && typeof state === 'object'\n  && typeof state.target === 'object' && state.target !== null && !Array.isArray(state.target)\n  && Array.isArray(state.selectedModules)\n  && state.selectedModules.every(m => typeof m === 'string' && m.length > 0)\n  && Array.isArray(state.operations);\nif (!ok) throw new Error(`State shape invalid before call: ${statePath}`);","typeGuard":"function hasValidStateShape(state) {\n  return !!state && typeof state === 'object' && !Array.isArray(state)\n    && typeof state.target === 'object' && state.target !== null && !Array.isArray(state.target)\n    && Array.isArray(state.selectedModules)\n    && state.selectedModules.every(m => typeof m === 'string' && m.length > 0)\n    && Array.isArray(state.operations);\n}","tryCatchPattern":"try {\n  validateManagedState(statePath);\n} catch (err) {\n  if (err.message.startsWith('Managed Claude install-state is invalid')) {\n    console.error(`${statePath} failed shape validation — restore or re-install`);\n    process.exitCode = 1;\n  } else throw err;\n}","preventionTips":["Treat install-state as machine-managed: edit through installer commands, not by hand.","Back up the state file before upgrades or migrations.","After an interrupted install, re-run the installer instead of salvaging partial state.","Version-check state format when syncing config directories between machines."],"tags":["state","validation","inventory"],"backgroundTag":"schema-validation-failed","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"}