{"record":{"id":"564cbb47627aa446","repo":"affaan-m/ECC","slug":"refusing-to-action-target-no-trusted-inst","errorCode":null,"errorMessage":"Refusing to ${action} '${target}': no trusted install root resolved.","messagePattern":"Refusing to (.+?) '(.+?)': no trusted install root resolved\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/path-safety.js","lineNumber":90,"sourceCode":"  }\n\n  try {\n    return resolveContainment(target, root).contained;\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Fail-closed guard: throw unless `target` is contained within `root`.\n * Returns the canonicalized target path on success.\n */\nfunction assertWithinTrustedRoot(target, root, action = 'write') {\n  if (!target || typeof target !== 'string') {\n    throw new Error(`Refusing to ${action}: missing destination path.`);\n  }\n  if (!root) {\n    throw new Error(`Refusing to ${action} '${target}': no trusted install root resolved.`);\n  }\n\n  let containment;\n  try {\n    containment = resolveContainment(target, root);\n  } catch {\n    containment = null;\n  }\n  if (!containment || !containment.contained) {\n    throw new Error(`Refusing to ${action} outside the install root: '${target}' is not within '${root}'.`);\n  }\n  return containment.realTarget;\n}\n\nmodule.exports = {\n  realpathNearestExisting,\n  isWithinRoot,\n  assertWithinTrustedRoot","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/path-safety.js#L72-L108","documentation":"assertWithinTrustedRoot() refuses to perform the requested action when the trusted root parameter is empty/falsy — i.e. the library could not resolve the trusted install root against which containment would be checked. This is a fail-closed design: without a verified root there is no safe boundary, so any write/repair is rejected instead of defaulting to the current directory.","triggerScenarios":"Calling assertWithinTrustedRoot(target, '') or assertWithinTrustedRoot(target, undefined), or indirectly when root-producing helpers (canonicalRoot, resolveAllowedProjectConfigHome, etc.) fail to resolve the install root — e.g. env var unset, config file absent, or the resolution function returned null.","commonSituations":"Running the tool outside a recognized install (no trusted root recorded); ECC-related env/config not set up after a fresh clone or plugin migration; the root config file was deleted or renamed; calling the low-level guard directly without resolving the root first.","solutions":["Ensure the trusted install root is resolved before the call — run the library's setup/init step or use its canonicalRoot() helper to obtain the root.","Set or repair the configuration/env that supplies the install root (e.g. the plugin install location, install manifest, or documented env var).","If calling the API directly, resolve and pass a real existing directory string as the root argument.","Reinstall or re-run the installer so the trusted root metadata is written to the expected location."],"exampleFix":"// before\nassertWithinTrustedRoot(target, process.env.MY_INSTALL_ROOT, 'write') // unset\n// after\nconst root = process.env.MY_INSTALL_ROOT || detectInstallRoot();\nif (!root) throw new Error('Install root not configured; run setup first');\nassertWithinTrustedRoot(target, root, 'write')","handlingStrategy":"try-catch","validationCode":"if (!root || typeof root !== 'string') {\n  throw new Error('Trusted install root is not configured; run the installer/setup step first.');\n}\nassertWithinTrustedRoot(target, root, action);","typeGuard":"function hasTrustedRoot(v) {\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":"try {\n  assertWithinTrustedRoot(target, root, 'write');\n} catch (e) {\n  if (/no trusted install root resolved/.test(e.message)) {\n    console.error('Install root missing — re-run setup or set the install-root config/env, then retry.');\n  } else throw e;\n}","preventionTips":["Always resolve the root through the library's canonicalRoot()/init step instead of passing ad-hoc paths.","Run the installer/setup after fresh clones, plugin migrations, or config cleanups.","Do not delete or rename the root metadata file the resolver depends on.","Fail fast at startup if the trusted root cannot be resolved, before any write operations."],"tags":["path-safety","configuration","fail-closed","filesystem"],"backgroundTag":"missing-config-value","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"}