unslothai/unsloth · warning · ValueError
Symbolic-link folders are not allowed
Error message
Symbolic-link folders are not allowed
What it means
ValueError raised when os.lstat on the expanded path shows it is itself a symbolic link. The folder-link policy forbids registering symlinks because the link target can be swapped after validation, defeating every later path-based check (sensitive-component scans, root checks) — a time-of-check/time-of-use bypass. Note the check uses lstat, so it inspects the final path component, not intermediate links.
Source
Thrown at studio/backend/core/rag/folder_sync.py:133
error = error.replace(os.path.normpath(native_path), "<native_path>")
return error
def _is_within(root: str, path: str) -> bool:
try:
return os.path.normcase(os.path.commonpath([root, path])) == os.path.normcase(root)
except ValueError:
return False
def validate_folder_path(path: str) -> str:
"""Apply the existing model scan-folder policy without persisting there."""
if not path or not path.strip() or "\x00" in path:
raise ValueError("Path cannot be empty")
expanded = os.path.abspath(os.path.expanduser(path))
try:
if stat.S_ISLNK(os.lstat(expanded).st_mode):
raise ValueError("Symbolic-link folders are not allowed")
except OSError as exc:
raise ValueError("Path does not exist") from exc
normalized = os.path.realpath(expanded)
uploads_root = os.path.realpath(str(rag_uploads_root()))
if _paths_overlap(_path_key(normalized), _path_key(uploads_root)):
raise ValueError("The managed RAG uploads folder cannot be linked")
from hub.storage.scan_folders import (
contains_sensitive_path_component,
is_denied_system_path,
)
from utils.paths.external_media import is_local_filesystem_root
if not os.path.isdir(normalized):
raise ValueError("Path must be a directory, not a file")
if not os.access(normalized, os.R_OK | os.X_OK):
raise ValueError("Path is not readable")
if is_local_filesystem_root(normalized):View on GitHub (pinned to 203007d190)
Solutions
- Register the real directory: pass the symlink's target (readlink -f) instead of the link.
- Use bind mounts (Linux) or junctions without a symlink final component if redirection is needed.
- Delete the symlink and pass the canonical absolute path.
Example fix
# before
validate_folder_path('/home/me/mydocs-link') # symlink
# after
import os
validate_folder_path(os.path.realpath('/home/me/mydocs-link')) # real target Defensive patterns
Strategy: validation
Validate before calling
import os, stat
def path_is_not_symlink(path: str) -> bool:
expanded = os.path.abspath(os.path.expanduser(path))
try:
return not stat.S_ISLNK(os.lstat(expanded).st_mode)
except OSError:
return True # nonexistent handled by its own check Try / catch
try:
validate_folder_path(path)
except ValueError as e:
if "Symbolic-link" not in str(e):
raise
import os
validate_folder_path(os.path.realpath(os.path.expanduser(path))) # retry with target Prevention
- Resolve symlinks client-side with realpath before submitting the folder.
- In folder-picker UIs, reject selections whose lstat mode has S_IFLNK.
- Educate users that links must point at real directories; use bind mounts for indirection.
When it happens
Trigger: Calling validate_folder_path('~/docs-link') where docs-link -> /home/user/Documents; linking into a mounted share via ln -s; a macOS alias or Linux symlink created for convenience pointing at the real folder.
Common situations: Users symlinking cloud-sync folders (Dropbox/Drive) into their home; container setups linking host volumes; symlinks created to shorten deep paths before registering them with RAG.
Related errors
- Credential or configuration directories are not allowed
- System directories are not allowed
- {_cn_fs.reason}
- Provider base URL points at a private address, which is disa
- Non-GGUF video loads are limited to unsloth/* repos, the off
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/75118a3124ecdba2.
Report an issue: GitHub.