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
Validation error from add_scan_folder_with_status: the path exists but os.path.isdir() is False — a regular file was submitted. Scan folders must be directories because the inventory walks them for model weights.
Source
Thrown at studio/backend/hub/storage/scan_folders.py:127
_ensure_schema(conn)
rows = conn.execute(
"SELECT id, path, created_at FROM scan_folders ORDER BY created_at"
).fetchall()
return [dict(row) for row in rows]
finally:
conn.close()
def add_scan_folder_with_status(path: str) -> tuple[dict, bool]:
"""Add a readable scan folder and return its row plus whether it was inserted."""
if not path or not path.strip():
raise ValueError("Path cannot be empty")
normalized = os.path.realpath(os.path.expanduser(normalize_path(path.strip())))
if not os.path.exists(normalized):
raise ValueError("Path does not exist")
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):
# A local fs root ("/", "C:\\") would expose denied system dirs via browse;
# a UNC share root (\\server\share) has none under it and stays registerable.
raise ValueError("The filesystem root cannot be registered")
if _contains_sensitive_path_component(normalized):
raise ValueError("Credential or configuration directories are not allowed")
is_win = platform.system() == "Windows"
check = os.path.normcase(normalized) if is_win else normalized
for prefix in _denied_path_prefixes():
if check == prefix or check.startswith(prefix + os.sep):
if prefix == "/run" and is_linux_run_media_path(check):
continue
raise ValueError(f"Path under {prefix} is not allowed")
conn = get_connection()View on GitHub (pinned to 203007d190)
Solutions
- Register the containing directory instead of the file.
- If the intent was to point at one model, use the model-path/custom-folder mechanism that accepts weight files, not scan folders.
Example fix
# before
add_scan_folder('/data/models/llama.gguf')
# after
add_scan_folder('/data/models') Defensive patterns
Strategy: validation
Validate before calling
import os
def is_registerable_dir(path: str) -> bool:
p = os.path.realpath(os.path.expanduser(path.strip()))
return os.path.isdir(p) Prevention
- In pickers, restrict selection to directories only.
- If the user picked a weight file, offer its parent directory automatically.
When it happens
Trigger: Registering a file like /data/models/model.gguf or /home/user/config.yaml as a scan folder.
Common situations: Users pasting the path to a downloaded weight file instead of its folder; drag-and-drop from a file manager yielding a file path; confusion between scan folders (directories) and model weight files (accepted elsewhere).
Related errors
- Path cannot be empty
- Path cannot be empty
- Path must be a directory, not a file
- Path does not exist
- Path is not readable
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/cf259845ffb58002.
Report an issue: GitHub.