unslothai/unsloth · warning · ValueError

Path is not readable

Error message

Path is not readable

What it means

Validation error from add_scan_folder_with_status: os.access(normalized, os.R_OK | os.X_OK) reports the backend process cannot read or traverse the directory. The folder may be browsable by another user but not by the account running studio, since os.access uses the real (not effective-filesystemACL) view of the current process.

Source

Thrown at studio/backend/hub/storage/scan_folders.py:129

            "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()
    try:
        _ensure_schema(conn)

View on GitHub (pinned to 203007d190)

Solutions

  1. Grant read+execute to the service user: `chmod o+rx /data/models` or chown/chgrp to the backend group.
  2. Verify as that user: `sudo -u <backend-user> test -r <path> -a -x <path> && echo ok`.
  3. Move the models under a shared location both users can access.

Example fix

# before: /home/alice/models is 0700, backend runs as 'studio'
sudo chmod o+rx /home/alice /home/alice/models
# after: backend can register /home/alice/models
Defensive patterns

Strategy: validation

Validate before calling

import os

def backend_can_read(path: str) -> bool:
    p = os.path.realpath(os.path.expanduser(path.strip()))
    return os.path.isdir(p) and os.access(p, os.R_OK | os.X_OK)

Prevention

When it happens

Trigger: Registering a 0700 directory owned by another user; a directory with mode 0600; running the backend under a restricted systemd user (DynamicUser) that lacks access to /home/*.

Common situations: Models stored in another user's home; permission tightening after a security pass; backend running as 'nobody'; directories on media mounted with permissions that exclude the service user.

Related errors


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