{"record":{"id":"c4bc0fb95f1c4c98","repo":"unslothai/unsloth","slug":"path-is-not-readable","errorCode":null,"errorMessage":"Path is not readable","messagePattern":"Path is not readable","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"studio/backend/core/rag/folder_sync.py","lineNumber":150,"sourceCode":"        if stat.S_ISLNK(os.lstat(expanded).st_mode):\n            raise ValueError(\"Symbolic-link folders are not allowed\")\n    except OSError as exc:\n        raise ValueError(\"Path does not exist\") from exc\n    normalized = os.path.realpath(expanded)\n    uploads_root = os.path.realpath(str(rag_uploads_root()))\n    if _paths_overlap(_path_key(normalized), _path_key(uploads_root)):\n        raise ValueError(\"The managed RAG uploads folder cannot be linked\")\n\n    from hub.storage.scan_folders import (\n        contains_sensitive_path_component,\n        is_denied_system_path,\n    )\n    from utils.paths.external_media import is_local_filesystem_root\n\n    if not os.path.isdir(normalized):\n        raise ValueError(\"Path must be a directory, not a file\")\n    if not os.access(normalized, os.R_OK | os.X_OK):\n        raise ValueError(\"Path is not readable\")\n    if is_local_filesystem_root(normalized):\n        raise ValueError(\"The filesystem root cannot be registered\")\n    try:\n        if Path(normalized) == Path.home().resolve():\n            raise ValueError(\"The entire home folder cannot be registered\")\n    except RuntimeError:\n        pass\n    if contains_sensitive_path_component(normalized):\n        raise ValueError(\"Credential or configuration directories are not allowed\")\n    if is_denied_system_path(normalized):\n        raise ValueError(\"System directories are not allowed\")\n    return normalized\n\n\ndef _root_identity(root: str) -> tuple[int, int]:\n    try:\n        root_stat = os.lstat(root)\n    except OSError as exc:","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/rag/folder_sync.py#L132-L168","documentation":"ValueError raised when os.access(normalized, R_OK | X_OK) fails: the process cannot read entries in or traverse into the directory. Even a valid directory is useless as a scan root if the app cannot list and descend into it, so the policy rejects it up front. The check runs as the app's effective UID, so root-owned or restricted directories fail here rather than producing empty or partial indexes.","triggerScenarios":"Registering a directory owned by another user with mode 700; a directory on a FUSE mount that denies the app's user; running the backend as a service account with a restricted umask/home; Windows ACLs denying the service account traversal.","commonSituations":"Docker containers where the host folder is owned by a UID different from the container user; system directories like /root or other users' homes; NAS mounts with restrictive permissions; services running as 'nobody'.","solutions":["Grant read+execute on the directory to the account running the backend: chmod o+rx (Linux) or adjust ACLs (Windows).","Move or copy the documents into a folder the app user owns.","Run the backend as a user with access to the share, or mount the share with credentials for that user."],"exampleFix":"# before\nchmod 700 /srv/docs  # only owner can enter; backend runs as different user\n\n# after\nchmod 755 /srv/docs  # backend user can read and traverse","handlingStrategy":"validation","validationCode":"import os\n\ndef folder_readable(path: str) -> bool:\n    expanded = os.path.realpath(os.path.abspath(os.path.expanduser(path)))\n    return os.path.isdir(expanded) and os.access(expanded, os.R_OK | os.X_OK)","typeGuard":null,"tryCatchPattern":"try:\n    validate_folder_path(path)\nexcept ValueError as e:\n    if str(e) != \"Path is not readable\":\n        raise\n    return bad_request(\"grant the app read+traverse permission on that folder\")","preventionTips":["Run the backend under a user/group with read access to all registered sources.","In containers, chown/bind-mount host folders to match the container UID.","Pre-flight os.access checks in deployment scripts for each folder you plan to register."],"tags":["permissions","filesystem","validation","paths"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}