Mintplex-Labs/anything-llm · warning · Error
Cannot copy symbolic link: ${source}. Symlinks are not allow
Error message
Cannot copy symbolic link: ${source}. Symlinks are not allowed during copy operations. What it means
Thrown by copyRecursive() in the filesystem copy-file plugin when fs.lstat() reports the source is a symbolic link. The tool deliberately refuses to traverse or copy symlinks as a security measure to prevent following links outside the allowed workspace. Because copyRecursive recurses into directories, a symlink nested anywhere inside a copied directory also triggers this.
Source
Thrown at server/utils/agents/aibitat/plugins/filesystem/copy-file.js:9
const fs = require("fs/promises");
const path = require("path");
const filesystem = require("./lib.js");
async function copyRecursive(source, destination) {
const lstat = await fs.lstat(source);
if (lstat.isSymbolicLink()) {
throw new Error(
`Cannot copy symbolic link: ${source}. Symlinks are not allowed during copy operations.`
);
}
if (lstat.isDirectory()) {
await fs.mkdir(destination, { recursive: true });
const entries = await fs.readdir(source);
for (const entry of entries) {
await copyRecursive(
path.join(source, entry),
path.join(destination, entry)
);
}
} else {
await fs.copyFile(source, destination);
}
}
View on GitHub (pinned to 526360e320)
Solutions
- Resolve the symlink to its real target before copying, then copy the resolved path (which itself must be within allowed directories).
- Exclude symlinked entries from the copy operation.
- Replace symlinks with real files if they must be copied.
- Copy individual real files rather than a directory containing symlinks.
Defensive patterns
Strategy: validation
Validate before calling
const fs = require("fs/promises");
async function assertNotSymlink(p) {
const st = await fs.lstat(p);
if (st.isSymbolicLink())
throw new Error(`Refusing to copy symlink ${p}; resolve it first`);
} Try / catch
// the tool handler already catches this and returns a string result;
// in custom callers, catch and resolve the link target instead
try { await copyRecursive(src, dst); }
catch (e) { if (e.message.includes("symbolic link")) { /* resolve real path */ } else throw e; } Prevention
- Resolve symlinks to their real targets before copying.
- Audit workspace directories for symlinks before bulk copy operations.
- Prefer copying real files rather than directories that may contain links.
When it happens
Trigger: Calling the filesystem-copy-file tool where the source path, or any entry within a source directory, is a symbolic link. The error fires before any copy attempt for that entry. The handler catches it and returns the message as a string result to the agent rather than throwing to the caller.
Common situations: User workspace contains symlinks (e.g., linked node_modules, config shortcuts); copying a directory tree that includes linked files; an agent attempting to back up a folder with shortcuts.
Related errors
- Access denied - symlink target outside allowed directories.
- Access denied - parent directory outside allowed directories
- Invalid path.
- Invalid path name
- Invalid folder name.
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/a2aa67b8e5a87203.
Report an issue: GitHub.