{"record":{"id":"3390b2a2b31981d2","repo":"unslothai/unsloth","slug":"path-is-not-readable-3390b2","errorCode":null,"errorMessage":"Path is not readable","messagePattern":"Path is not readable","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"warning","filePath":"studio/backend/hub/storage/scan_folders.py","lineNumber":129,"sourceCode":"            \"SELECT id, path, created_at FROM scan_folders ORDER BY created_at\"\n        ).fetchall()\n        return [dict(row) for row in rows]\n    finally:\n        conn.close()\n\n\ndef add_scan_folder_with_status(path: str) -> tuple[dict, bool]:\n    \"\"\"Add a readable scan folder and return its row plus whether it was inserted.\"\"\"\n    if not path or not path.strip():\n        raise ValueError(\"Path cannot be empty\")\n    normalized = os.path.realpath(os.path.expanduser(normalize_path(path.strip())))\n\n    if not os.path.exists(normalized):\n        raise ValueError(\"Path does not exist\")\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        # A local fs root (\"/\", \"C:\\\\\") would expose denied system dirs via browse;\n        # a UNC share root (\\\\server\\share) has none under it and stays registerable.\n        raise ValueError(\"The filesystem root cannot be registered\")\n    if _contains_sensitive_path_component(normalized):\n        raise ValueError(\"Credential or configuration directories are not allowed\")\n\n    is_win = platform.system() == \"Windows\"\n    check = os.path.normcase(normalized) if is_win else normalized\n    for prefix in _denied_path_prefixes():\n        if check == prefix or check.startswith(prefix + os.sep):\n            if prefix == \"/run\" and is_linux_run_media_path(check):\n                continue\n            raise ValueError(f\"Path under {prefix} is not allowed\")\n\n    conn = get_connection()\n    try:\n        _ensure_schema(conn)","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/hub/storage/scan_folders.py#L111-L147","documentation":"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.","triggerScenarios":"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/*.","commonSituations":"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.","solutions":["Grant read+execute to the service user: `chmod o+rx /data/models` or chown/chgrp to the backend group.","Verify as that user: `sudo -u <backend-user> test -r <path> -a -x <path> && echo ok`.","Move the models under a shared location both users can access."],"exampleFix":"# before: /home/alice/models is 0700, backend runs as 'studio'\nsudo chmod o+rx /home/alice /home/alice/models\n# after: backend can register /home/alice/models","handlingStrategy":"validation","validationCode":"import os\n\ndef backend_can_read(path: str) -> bool:\n    p = os.path.realpath(os.path.expanduser(path.strip()))\n    return os.path.isdir(p) and os.access(p, os.R_OK | os.X_OK)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run the os.access check as the service user, not your own account.","Grant r+x on every parent component, not just the leaf directory.","For systemd services, avoid DynamicUser/restrictive User= for hosts holding model data."],"tags":["validation","scan-folders","permissions"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}