{"record":{"id":"ecbca2d764d8b29e","repo":"affaan-m/ECC","slug":"refusing-to-apply-install-operation-missing-desti","errorCode":null,"errorMessage":"Refusing to apply install operation: missing destination path.","messagePattern":"Refusing to apply install operation: missing destination path\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"scripts/lib/install/apply.js","lineNumber":198,"sourceCode":"  return value;\n}\n\nfunction findHooksOperation(plan, hooksDestinationPath) {\n  return plan.operations.find(item => (\n    item.destinationPath === hooksDestinationPath\n    && item.moduleId === 'hooks-runtime'\n    && typeof item.sourcePath === 'string'\n  ));\n}\n\nfunction isMcpConfigPath(filePath) {\n  const basename = path.basename(String(filePath || ''));\n  return basename === '.mcp.json' || basename === 'mcp.json';\n}\n\nfunction assertSafeInstallOperation(plan, operation) {\n  if (!operation || typeof operation.destinationPath !== 'string') {\n    throw new Error('Refusing to apply install operation: missing destination path.');\n  }\n\n  const targetRoot = plan && plan.targetRoot;\n  assertWithinTrustedRoot(operation.destinationPath, targetRoot, 'install ECC file');\n\n  const resolvedRoot = path.resolve(targetRoot);\n  const resolvedTarget = path.resolve(operation.destinationPath);\n  const relativePath = path.relative(resolvedRoot, resolvedTarget);\n  const segments = relativePath ? relativePath.split(path.sep) : [];\n  for (const segmentIndex of Array.from({ length: segments.length + 1 }, (_value, index) => index)) {\n    const currentPath = segmentIndex === 0\n      ? resolvedRoot\n      : path.join(resolvedRoot, ...segments.slice(0, segmentIndex));\n    try {\n      const stats = fs.lstatSync(currentPath);\n      if (stats.isSymbolicLink()) {\n        throw new Error(\n          `Refusing to install ECC file through symlinked path: '${currentPath}'.`","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/lib/install/apply.js#L180-L216","documentation":"Thrown by assertSafeInstallOperation in scripts/lib/install/apply.js. The guard is invoked twice per operation inside applyInstallPlan (before and after mkdirSync) and its first check is that operation is truthy and operation.destinationPath is a string. Without a destination path the installer cannot confine the write to a trusted root, so it refuses rather than guessing. This is a fail-closed security guard, not a normal validation error.","triggerScenarios":"A plan whose operations array contains a null entry, an object missing destinationPath, or an object whose destinationPath is undefined/a number/an empty value. Happens with hand-built operation objects or a stale install-state replayed under a renamed schema.","commonSituations":"Custom adapter that emits operations without going through createManagedOperation; an old install-state file whose field names no longer match; a programmatic plan assembled by hand without the destinationPath field.","solutions":["Inspect plan.operations and confirm every entry has a non-empty string destinationPath.","Build operations through createManagedOperation (helpers.js) so destinationPath is always set.","If you are replaying an old install-state, regenerate the plan from the current ECC version instead of reusing the file.","Add a unit test that asserts every emitted operation passes a destinationPath string check."],"exampleFix":"// before\nplan.operations.push({ kind: 'copy-file', sourcePath: src });\n\n// after\nplan.operations.push({\n  kind: 'copy-file',\n  sourcePath: src,\n  destinationPath: path.join(targetRoot, 'file.txt'),\n});","handlingStrategy":"validation","validationCode":"function assertOperationsWellFormed(operations) {\n  for (const op of operations) {\n    if (!op || typeof op.destinationPath !== 'string' || op.destinationPath.length === 0) {\n      throw new Error(`Operation missing destinationPath: ${JSON.stringify(op)}`);\n    }\n  }\n}\nassertOperationsWellFormed(plan.operations);","typeGuard":"function isInstallOperation(value) {\n  return Boolean(\n    value && typeof value === 'object'\n    && typeof value.destinationPath === 'string'\n    && typeof value.kind === 'string'\n  );\n}","tryCatchPattern":"try {\n  applyInstallPlan(plan);\n} catch (err) {\n  if (/missing destination path/.test(err.message)) {\n    console.error('Malformed operations:', plan.operations.filter(o => !o || typeof o.destinationPath !== 'string'));\n  }\n  throw err;\n}","preventionTips":["Never hand-construct operation objects; always use createManagedOperation from helpers.js.","Add a unit test asserting every emitted operation has a string destinationPath.","Do not replay install-state files across ECC versions without re-validating the schema."],"tags":["security","install-safety","validation","invariant"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}