affaan-m/ECC · critical

Refusing to outside the install root: ' ' is not within ' '.

Error message

Refusing to ${action} outside the install root: '${target}' is not within '${root}'.

What it means

assertWithinTrustedRoot() resolves both paths (including symlinks via realpath of the nearest existing ancestor) and rejects the operation when the target's canonical location is not contained inside the trusted root. This is the library's core anti-path-traversal guard: it blocks writes/repairs that would escape the install root through '..', symlink redirection, or pre-resolved absolute paths pointing elsewhere.

Solutions

  1. Verify the target path in the message is actually inside the trusted root shown in the message; correct the path construction to stay within it.
  2. Resolve symlinks: if your project dir is symlinked into the root, ensure operations target the real path or re-point the symlink inside the root.
  3. Sanitize/normalize untrusted input: strip '..' segments and resolve relative to the root before calling.
  4. If a write legitimately belongs outside the install root (e.g. user home config), use the library's dedicated helper for allowed external locations (e.g. resolveAllowedProjectConfigHome) instead of forcing containment.

Example fix

// before
const dest = path.join(root, userInput); // userInput = '../../.bashrc'
assertWithinTrustedRoot(dest, root, 'write');
// after
const rel = path.normalize(userInput).replace(/^(\.\.(\/|\\|$))+/, '');
assertWithinTrustedRoot(path.join(root, rel), root, 'write');
Defensive patterns

Strategy: validation

Validate before calling

const path = require('path');
function isInsideRoot(target, root) {
  const rel = path.relative(path.resolve(root), path.resolve(target));
  return rel !== '' && !rel.startsWith('..') && !path.isAbsolute(rel);
}
if (!isInsideRoot(target, root)) {
  throw new Error(`Refusing to write outside install root: ${target}`);
}
assertWithinTrustedRoot(target, root, 'write');

Type guard

function isContainedPath(target, root) {
  const rel = require('path').relative(root, target);
  return rel !== '' && !rel.startsWith('..');
}

Try / catch

try {
  const real = assertWithinTrustedRoot(target, root, 'write');
} catch (e) {
  if (/outside the install root/.test(e.message)) {
    console.error(`Path traversal blocked: ${target} escapes ${root}. Check for '../' segments or symlinks.`);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling assertWithinTrustedRoot('/etc/passwd', installRoot, 'write'); targets using '..' segments that escape the root; symlinked targets whose real path resolves outside the root; paths constructed from untrusted input (user-supplied filenames, external config) that happen to point outside the boundary.

Common situations: Repair/copy logic deriving destination paths from user input or untrusted file contents; moving shared config to a home directory outside the install tree; symlinked project directories (dotfiles managers like GNU stow) making the real path land outside the assumed root; accidental use of an absolute path from another project.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/de2a0c8fd10c542d. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/path-safety.js:100

 * Fail-closed guard: throw unless `target` is contained within `root`.
 * Returns the canonicalized target path on success.
 */
function assertWithinTrustedRoot(target, root, action = 'write') {
  if (!target || typeof target !== 'string') {
    throw new Error(`Refusing to ${action}: missing destination path.`);
  }
  if (!root) {
    throw new Error(`Refusing to ${action} '${target}': no trusted install root resolved.`);
  }

  let containment;
  try {
    containment = resolveContainment(target, root);
  } catch {
    containment = null;
  }
  if (!containment || !containment.contained) {
    throw new Error(`Refusing to ${action} outside the install root: '${target}' is not within '${root}'.`);
  }
  return containment.realTarget;
}

module.exports = {
  realpathNearestExisting,
  isWithinRoot,
  assertWithinTrustedRoot
};

View on GitHub (pinned to 8321021c54)