{"record":{"id":"0cf45429aab0002d","repo":"affaan-m/ECC","slug":"invalid-canonical-install-state-required-projecti","errorCode":null,"errorMessage":"Invalid canonical install-state: required projection fields are missing","messagePattern":"Invalid canonical install-state: required projection fields are missing","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/state-store/install-state-projection.js","lineNumber":21,"sourceCode":"const path = require('path');\n\nconst MANAGED_FILE_HEALTH_CODES = new Set([\n  'missing-target-root',\n  'unsafe-managed-destination',\n  'unsafe-repair-source',\n  'missing-managed-files',\n  'drifted-managed-files',\n  'missing-source-files',\n  'unverified-managed-operations',\n]);\n\nfunction cloneJsonValue(value) {\n  return value === undefined ? undefined : JSON.parse(JSON.stringify(value));\n}\n\nfunction buildInstallStateStoreRecord(state) {\n  if (!state || !state.target || !state.request || !state.resolution || !state.source) {\n    throw new Error('Invalid canonical install-state: required projection fields are missing');\n  }\n\n  return {\n    targetId: state.target.id,\n    targetRoot: state.target.root,\n    profile: state.request.profile ?? null,\n    modules: Array.isArray(state.resolution.selectedModules)\n      ? [...state.resolution.selectedModules]\n      : [],\n    operations: Array.isArray(state.operations)\n      ? state.operations.map(operation => cloneJsonValue(operation))\n      : [],\n    installedAt: state.installedAt,\n    sourceVersion: state.source.repoVersion ?? null,\n  };\n}\n\nfunction warningFor(record, code, message) {","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/state-store/install-state-projection.js#L3-L39","documentation":"buildInstallStateStoreRecord projects a canonical install-state into a storage record, but first requires the state object to carry all four mandatory sections: target, request, resolution, and source. If any of them is missing (or state itself is null/undefined), the projection is considered invalid and this error is thrown. It signals a corrupt or truncated install-state rather than a bad individual field value.","triggerScenarios":"Calling buildInstallStateStoreRecord with null/undefined, or with a state object built by an older/different version missing e.g. resolution or source; destructuring an incomplete record loaded from disk and passing the fragment in; a partial object literal in tests.","commonSituations":"Schema drift after a library upgrade renamed or removed one of the sections; a migration that copied only part of the state; hand-constructed fixtures missing optional-looking sections that are actually required; loading a JSON file that was truncated by a crashed write.","solutions":["Log/inspect the state object and ensure target, request, resolution, and source are all present before calling","Rebuild the install-state through the library's canonical creation path instead of hand-assembling it","If data came from disk, validate it against the expected schema and re-run the install to regenerate the state","After an upgrade, migrate old states to the new shape before projecting"],"exampleFix":"// before\nbuildInstallStateStoreRecord({ target, request }); // missing resolution & source\n// after\nbuildInstallStateStoreRecord({ target, request, resolution, source });","handlingStrategy":"validation","validationCode":"const REQUIRED = ['target', 'request', 'resolution', 'source'];\nconst missing = REQUIRED.filter(k => !state?.[k]);\nif (missing.length) {\n  throw new Error(`install-state missing sections: ${missing.join(', ')}`);\n}","typeGuard":"function isCompleteInstallState(s) {\n  return Boolean(s && s.target && s.request && s.resolution && s.source);\n}","tryCatchPattern":"try {\n  const record = buildInstallStateStoreRecord(state);\n} catch (err) {\n  if (err.message.startsWith('Invalid canonical install-state')) {\n    console.error('State object incomplete — regenerate via canonical install flow');\n    state = regenerateInstallState();\n    return buildInstallStateStoreRecord(state);\n  } throw err;\n}","preventionTips":["Build install-states only through the library's canonical creation path","Validate JSON loaded from disk against the state schema before projecting","After upgrades, run state migrations before touching stored records","Never hand-write partial fixture objects for required sections"],"tags":["validation","schema"],"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"}