{"record":{"id":"dba16511313e7104","repo":"affaan-m/ECC","slug":"missing-merge-payload-for-repair-operation-dest","errorCode":null,"errorMessage":"Missing merge payload for repair: ${operation.destinationPath}","messagePattern":"Missing merge payload for repair: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/install-lifecycle.js","lineNumber":621,"sourceCode":"\n    copyContainedFile(sourcePath, operation.destinationPath, trustedRoot, 'repair');\n    return operation.destinationPath;\n  }\n\n  if (operation.kind === 'render-template') {\n    const renderedContent = getOperationTextContent(operation);\n    if (renderedContent === null) {\n      throw new Error(`Missing rendered content for repair: ${operation.destinationPath}`);\n    }\n\n    writeContainedFile(operation.destinationPath, renderedContent, trustedRoot, 'repair');\n    return operation.destinationPath;\n  }\n\n  if (operation.kind === 'merge-json') {\n    const payload = getOperationJsonPayload(operation);\n    if (payload === undefined) {\n      throw new Error(`Missing merge payload for repair: ${operation.destinationPath}`);\n    }\n\n    const existingDestination = getContainedExistingPath(operation.destinationPath, trustedRoot, 'repair');\n    const currentValue = existingDestination\n      ? readJsonNoFollow(\n        getManagedDestination(existingDestination, trustedRoot, 'repair').managedPath\n      )\n      : {};\n    const mergedValue = deepMergeJson(currentValue, payload);\n\n    writeContainedFile(operation.destinationPath, formatJson(mergedValue), trustedRoot, 'repair');\n    return operation.destinationPath;\n  }\n\n  if (operation.kind === 'remove') {\n    const removedPath = removeContainedPath(\n      operation.destinationPath,\n      trustedRoot,","sourceCodeStart":603,"sourceCodeEnd":639,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/install-lifecycle.js#L603-L639","documentation":"For a 'merge-json' repair, getOperationJsonPayload must return a defined payload object. If it returns undefined (operation has no `payload`/`json` field), the merge cannot be computed, so the repair is rejected. Guards against writing an uncontrolled merged result from an attacker-controllable install-state.","triggerScenarios":"Repair of a merge-json operation whose install-state entry lacks the payload field, or whose payload was set to null/undefined by a schema drift or hand edit. Triggered inside executeRepairOperation for operation.kind === 'merge-json'.","commonSituations":"Hand-edited install-state; install-state produced by an older version that stored the payload under a different key; partial write of the state file after a crash.","solutions":["Inspect the operation entry in the install-state file at record.installStatePath and confirm it carries a JSON payload.","Uninstall the target and re-install to regenerate a valid install-state.","If merging into a user-edited config (e.g. settings.json), back up the target file first so re-install can re-apply the merge cleanly.","Upgrade the installer package so the operation schema matches what was recorded."],"exampleFix":"// before: { kind: 'merge-json', destinationPath: '...', /* payload missing */ }\n// after:\n./install.sh --target claude --uninstall\n./install.sh --target claude","handlingStrategy":"validation","validationCode":"function hasMergePayload(op) {\n  if (op.kind !== 'merge-json') return true;\n  return getOperationJsonPayload(op) !== undefined;\n}\n// before repair: state.operations.every(hasMergePayload)","typeGuard":"function isMergeableOperation(op) {\n  return op.kind !== 'merge-json' || getOperationJsonPayload(op) !== undefined;\n}","tryCatchPattern":"try {\n  await executeRepairOperation(repoRoot, op, trustedRoot);\n} catch (err) {\n  if (err.message.startsWith('Missing merge payload for repair')) {\n    // reinstall to repopulate the payload, then repair\n  } else throw err;\n}","preventionTips":["Treat install-state as installer-owned; do not strip payload fields.","Reinstall after schema migrations that touch merge-json operations.","Back up merge targets (e.g. settings.json) before repair so manual revert is possible.","Validate the install-state shape programmatically before invoking repair."],"tags":["repair","install","validation","merge-json"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}