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
- Request files with paths inside the workspace root; use relative paths from the project directory.
- For files outside the workspace, change to that project directory (set workspaceCwd) or open a session rooted at the containing project.
- If a legitimate file fails due to symlinks, restructure so the target is inside the workspace or copy it in.
- 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
- Use relative paths from the workspace root in tool calls.
- Reject '..' segments and absolute paths in client input.
- Watch for symlinks pointing outside the repo.
- Open sessions with cwd set to the project you need to read.
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.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Refusing inject path for non-UUID agent id
- Refusing inject write outside agent memory/log
- Admin endpoints are only accessible from localhost
- Bun installation completed but binary not found. Please…
- Cannot lazy-spawn worker: Bun runtime not found on PATH
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)