unslothai/unsloth · warning · ValueError
Path must be a directory, not a file
Error message
Path must be a directory, not a file
What it means
ValueError raised when the fully normalized path (after realpath resolution of symlinks and . /..) exists but is not a directory — i.e. it is a regular file (or special file). The folder-link feature scans directory trees, so registering a file has no meaningful semantics and is rejected explicitly with a message distinguishing it from 'does not exist'.
Source
Thrown at studio/backend/core/rag/folder_sync.py:148
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):
raise ValueError("The filesystem root cannot be registered")
try:
if Path(normalized) == Path.home().resolve():
raise ValueError("The entire home folder cannot be registered")
except RuntimeError:
pass
if contains_sensitive_path_component(normalized):
raise ValueError("Credential or configuration directories are not allowed")
if is_denied_system_path(normalized):
raise ValueError("System directories are not allowed")
return normalized
def _root_identity(root: str) -> tuple[int, int]:
try:View on GitHub (pinned to 203007d190)
Solutions
- Pass the containing directory of the file you want indexed — the scanner recurses into it.
- Configure the client-side folder picker to directory-selection mode.
- If a directory was expected, check whether something replaced it with a file of the same name.
Example fix
# before
validate_folder_path('/home/me/docs/report.pdf')
# after
validate_folder_path('/home/me/docs') # scanner indexes files inside Defensive patterns
Strategy: validation
Validate before calling
import os
def folder_is_directory(path: str) -> bool:
expanded = os.path.realpath(os.path.abspath(os.path.expanduser(path)))
return os.path.isdir(expanded) Try / catch
try:
validate_folder_path(path)
except ValueError as e:
if "must be a directory" not in str(e):
raise
import os
validate_folder_path(os.path.dirname(os.path.abspath(path))) # register parent dir Prevention
- Use a directory-only picker (e.g. webkitdirectory / SHBrowseForFolders), not a file input.
- Submit dirname(file) when users drag a single document.
- Validate isdir on the client before the round-trip.
When it happens
Trigger: Calling validate_folder_path on a path to a .txt/.pdf file instead of its containing folder; drag-and-drop of a file (not folder) from an OS file picker into the link form; a path whose final component was replaced by a file after earlier validation.
Common situations: Users pasting a document path instead of its directory; file pickers configured without directory-only mode; frontend passing the wrong field (file path instead of folder path).
Related errors
- Path cannot be empty
- Path does not exist
- Path is not readable
- The filesystem root cannot be registered
- local cache path is too long (max 4096 chars)
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/165c3e9d287cc13c.
Report an issue: GitHub.