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

  1. Register the real directory: pass the symlink's target (readlink -f) instead of the link.
  2. Use bind mounts (Linux) or junctions without a symlink final component if redirection is needed.
  3. 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

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


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/75118a3124ecdba2. Report an issue: GitHub.