{"record":{"id":"7e925737c5cea7b5","repo":"unslothai/unsloth","slug":"path-under-prefix-is-not-allowed","errorCode":null,"errorMessage":"Path under {prefix} is not allowed","messagePattern":"Path under (.+?) is not allowed","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"warning","filePath":"studio/backend/hub/storage/scan_folders.py","lineNumber":143,"sourceCode":"        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)\n        now = datetime.now(timezone.utc).isoformat()\n        if is_win:\n            existing = conn.execute(\n                \"SELECT id, path, created_at FROM scan_folders WHERE path = ? COLLATE NOCASE\",\n                (normalized,),\n            ).fetchone()\n        else:\n            existing = conn.execute(\n                \"SELECT id, path, created_at FROM scan_folders WHERE path = ?\",\n                (normalized,),\n            ).fetchone()\n        if existing is not None:\n            return dict(existing), False\n        inserted = False","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/hub/storage/scan_folders.py#L125-L161","documentation":"Validation error from add_scan_folder_with_status: the normalized path equals or sits under a denied system prefix. The denylist is platform-specific — Linux: /proc, /sys, /dev, /etc, /boot, /run; macOS: /System, /Library, /dev, /etc, /private/etc, /tmp, /private/tmp, /var, /private/var; Windows: SystemRoot, ProgramFiles, ProgramFiles(x86) — with a carve-out letting /run/media/* removable mounts through. Case-insensitive on Windows via os.path.normcase.","triggerScenarios":"Registering /etc/models, /var/lib/models, /tmp/foo, C:\\Windows\\..., C:\\Program Files\\..., or any descendant. Registering /run/media/user/USB0/models succeeds (carve-out); /run/systemd fails.","commonSituations":"Sysadmin-style habits of putting data in /var or /opt-adjacent system trees; Docker/Kubernetes setups where the host /etc is bind-mounted inside the container; macOS users picking /tmp for a quick test.","solutions":["Move the models to a non-system tree such as /data/models, /srv/models, /home/user/models, or /opt/studio-models (not in the denylist).","On Linux removable media, use /run/media/<user>/<volume>/models which the carve-out allows.","For containerized studio, register a path inside the container's own writable layer or an explicitly mounted data volume."],"exampleFix":"# before\nadd_scan_folder('/var/lib/studio/models')\n# after\nadd_scan_folder('/srv/studio/models')","handlingStrategy":"validation","validationCode":"from storage.scan_folders import is_denied_system_path\nimport os\n\ndef scan_folder_allowed(path: str) -> bool:\n    p = os.path.realpath(os.path.expanduser(path.strip()))\n    return not is_denied_system_path(p)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store models in user/data trees (/data, /srv, /home), never /etc, /var, /tmp, /proc, C:\\\\Windows, or Program Files.","Reuse is_denied_system_path() in UI validation so users learn the policy before submitting.","On Linux, keep removable-media scans under /run/media/<user>/<vol> — it is the allowed carve-out."],"tags":["validation","scan-folders","security","path-policy","cross-platform"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}