{"record":{"id":"27abc046693ef31c","repo":"affaan-m/ECC","slug":"missing-rendered-content-for-repair-operation-d","errorCode":null,"errorMessage":"Missing rendered content for repair: ${operation.destinationPath}","messagePattern":"Missing rendered content for repair: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/install-lifecycle.js","lineNumber":611,"sourceCode":"\nfunction executeRepairOperation(repoRoot, operation, trustedRoot) {\n  // Install-state is attacker-controllable; never write/delete outside the\n  // adapter-derived trusted root, regardless of what the state file claims\n  // (GHSA-hfpv-w6mp-5g95).\n  if (operation.kind === 'copy-file') {\n    const sourcePath = resolveOperationSourcePath(repoRoot, operation);\n    if (!sourcePath || !fs.existsSync(sourcePath)) {\n      throw new Error(`Missing source file for repair: ${sourcePath || operation.sourceRelativePath}`);\n    }\n\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      : {};","sourceCodeStart":593,"sourceCodeEnd":629,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/install-lifecycle.js#L593-L629","documentation":"For a 'render-template' repair operation the installer asks getOperationTextContent for the rendered body. If it returns null (no `text`/`textContent`/inline body on the operation record), the repair cannot proceed because there is nothing to write. Like 162, the install-state is treated as attacker-controllable, so missing content is fatal rather than synthesized.","triggerScenarios":"Repair runs against an install-state whose render-template operation is missing its text content field, or whose content field was stripped/corrupted. Also after a version downgrade where the operation schema for template content changed.","commonSituations":"Install-state file edited by hand or partially overwritten; older install-state from a previous ECC version where the template body lived in a different field; a failed prior write truncated the state file.","solutions":["Open the install-state file at record.installStatePath and inspect the offending operation entry — confirm it has a non-empty text/textContent body.","If the entry is malformed, uninstall the affected target and re-install fresh so a correct state is generated.","Upgrade the installer to a version whose operation schema matches the recorded operation.","Restore the install-state file from backup if available."],"exampleFix":"// before: operation = { kind: 'render-template', destinationPath: '...', /* no text */ }\n// after: uninstall + reinstall to regenerate state\n./install.sh --target claude --uninstall\n./install.sh --target claude","handlingStrategy":"validation","validationCode":"function hasRenderableContent(op) {\n  if (op.kind !== 'render-template') return true;\n  return getOperationTextContent(op) !== null;\n}\n// before repair: state.operations.every(hasRenderableContent)","typeGuard":"function isRenderableOperation(op) {\n  return op.kind !== 'render-template' || getOperationTextContent(op) !== null;\n}","tryCatchPattern":"try {\n  await executeRepairOperation(repoRoot, op, trustedRoot);\n} catch (err) {\n  if (err.message.startsWith('Missing rendered content for repair')) {\n    // reinstall the target to regenerate the operation with content\n  } else throw err;\n}","preventionTips":["Never hand-edit render-template operations in the install-state.","Reinstall when upgrading across versions that changed the operation schema.","Back up install-state before any manual modification.","If a template source changes, re-run install so the recorded content is refreshed."],"tags":["repair","install","validation","template"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}