affaan-m/ECC · error · Error

Refusing to access memory through symlink root

Error message

Refusing to access memory through symlink root: ${root}

What it means

assertWithinTrustedRoot throws when the configured memory root for a scope resolves outside its trusted boundary via a symlink, refusing potential symlink-escape attacks on the memory vault. The faulting input is the symlinked root path shown in the message.

Solutions

  1. Replace the symlink with a real directory, or point the scope's root env var at the real path.
  2. Ensure the trusted boundary directory contains the actual (resolved) root.
  3. Do not relocate memory roots via symlinks across filesystem boundaries.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at scripts/lib/memory-vault.js:111 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at scripts/lib/memory-vault.js:111

  });
  return Object.freeze(roots);
}

function assertMemoryRootSafe(roots, scope) {
  if (!roots || typeof roots !== 'object' || Array.isArray(roots)) {
    throw new Error('Memory roots must include a trusted boundary policy.');
  }
  const root = roots[scope];
  if (typeof root !== 'string' || root.length === 0) {
    throw new Error(`No memory root is configured for scope "${scope}".`);
  }
  const boundary = roots[VAULT_ROOT_BOUNDARIES]?.[scope];
  if (typeof boundary !== 'string' || boundary.length === 0) {
    throw new Error(`No trusted boundary policy is configured for memory scope "${scope}".`);
  }
  assertWithinTrustedRoot(root, boundary, 'access memory through a symlink');
  if (fs.existsSync(root) && fs.lstatSync(root).isSymbolicLink()) {
    throw new Error(`Refusing to access memory through symlink root: ${root}`);
  }
  return root;
}

function assertMemoryDirectorySafe(directory, root) {
  assertWithinTrustedRoot(directory, root, 'access memory directory');
  if (fs.existsSync(directory) && fs.lstatSync(directory).isSymbolicLink()) {
    throw new Error(`Refusing to access memory through symlink directory: ${directory}`);
  }
  return directory;
}

function sameFileIdentity(left, right) {
  // The inode is the primary identity signal and must always match.
  if (left.ino !== right.ino) {
    return false;
  }
  // libuv 1.49.0 through 1.50.x resolve path-based stat() and lstat() on Windows

View on GitHub (pinned to 8321021c54)