thedotmack/claude-mem · error

Access denied: " " resolves outside the workspace ( ). MCP…

Error message

Access denied: "${filePath}" resolves outside the workspace (${root}). MCP file tools can only read files within the current project.

What it means

After resolving symlinks and normalizing, resolveWithinWorkspace verifies the resolved path is the workspace root itself or lies beneath it (resolved === root or starts with root + sep). It throws this access-denied error otherwise, enforcing that MCP file tools only read files inside the current project.

Solutions

  1. Request files with paths inside the workspace root; use relative paths from the project directory.
  2. For files outside the workspace, change to that project directory (set workspaceCwd) or open a session rooted at the containing project.
  3. If a legitimate file fails due to symlinks, restructure so the target is inside the workspace or copy it in.
  4. Check that process.cwd()/workspaceCwd is the intended project root before calling.

Example fix

// before
await resolveWithinWorkspace('/etc/passwd');
// after
await resolveWithinWorkspace('src/config.ts'); // within workspace cwd
Defensive patterns

Strategy: validation

Validate before calling

const root = resolve(process.cwd());
const resolved = resolve(root, inputPath);
if (resolved !== root && !resolved.startsWith(root + sep)) {
  throw new Error('path escapes workspace: ' + inputPath);
}

Try / catch

try {
  const resolved = await resolveWithinWorkspace(userPath);
} catch (err) {
  if (String(err).includes('resolves outside the workspace')) {
    return mcpError(403, 'Only files inside the current project can be read.');
  }
  throw err;
}

Prevention

When it happens

Trigger: A read is requested for an absolute path outside the workspace (/etc/passwd), a '../' traversal escaping the root, or a symlink inside the workspace pointing to an external target — the realpath resolution lands outside root.

Common situations: User asks the agent to read ~/.ssh/id_rsa or a sibling project; a symlinked node_modules or vendored directory points outside the repo; workspace root changed (different cwd) so previously-valid paths now escape.

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 thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/5b5e789c125a28f1. Report an issue: GitHub.

Appendix: source

Thrown at src/services/smart-file-read/workspace-path.ts:43

export async function resolveWithinWorkspace(
  filePath: string,
  workspaceCwd: string = process.cwd(),
): Promise<string> {
  if (typeof filePath !== 'string' || filePath.trim().length === 0) {
    throw new Error('file_path is required');
  }

  const root = await realpath(resolve(workspaceCwd));
  const lexicallyResolved = resolve(root, expandLeadingTilde(filePath.trim()));
  let resolved: string;
  try {
    resolved = await realpath(lexicallyResolved);
  } catch {
    resolved = lexicallyResolved;
  }

  if (resolved !== root && !resolved.startsWith(root + sep)) {
    throw new Error(
      `Access denied: "${filePath}" resolves outside the workspace (${root}). ` +
      'MCP file tools can only read files within the current project.',
    );
  }

  return resolved;
}

View on GitHub (pinned to d8bc9755e7)