{"record":{"id":"75118a3124ecdba2","repo":"unslothai/unsloth","slug":"symbolic-link-folders-are-not-allowed","errorCode":null,"errorMessage":"Symbolic-link folders are not allowed","messagePattern":"Symbolic-link folders are not allowed","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"studio/backend/core/rag/folder_sync.py","lineNumber":133,"sourceCode":"        error = error.replace(os.path.normpath(native_path), \"<native_path>\")\n    return error\n\n\ndef _is_within(root: str, path: str) -> bool:\n    try:\n        return os.path.normcase(os.path.commonpath([root, path])) == os.path.normcase(root)\n    except ValueError:\n        return False\n\n\ndef validate_folder_path(path: str) -> str:\n    \"\"\"Apply the existing model scan-folder policy without persisting there.\"\"\"\n    if not path or not path.strip() or \"\\x00\" in path:\n        raise ValueError(\"Path cannot be empty\")\n    expanded = os.path.abspath(os.path.expanduser(path))\n    try:\n        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):","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/rag/folder_sync.py#L115-L151","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Register the real directory: pass the symlink's target (readlink -f) instead of the link.","Use bind mounts (Linux) or junctions without a symlink final component if redirection is needed.","Delete the symlink and pass the canonical absolute path."],"exampleFix":"# before\nvalidate_folder_path('/home/me/mydocs-link')  # symlink\n\n# after\nimport os\nvalidate_folder_path(os.path.realpath('/home/me/mydocs-link'))  # real target","handlingStrategy":"validation","validationCode":"import os, stat\n\ndef path_is_not_symlink(path: str) -> bool:\n    expanded = os.path.abspath(os.path.expanduser(path))\n    try:\n        return not stat.S_ISLNK(os.lstat(expanded).st_mode)\n    except OSError:\n        return True  # nonexistent handled by its own check","typeGuard":null,"tryCatchPattern":"try:\n    validate_folder_path(path)\nexcept ValueError as e:\n    if \"Symbolic-link\" not in str(e):\n        raise\n    import os\n    validate_folder_path(os.path.realpath(os.path.expanduser(path)))  # retry with target","preventionTips":["Resolve symlinks client-side with realpath before submitting the folder.","In folder-picker UIs, reject selections whose lstat mode has S_IFLNK.","Educate users that links must point at real directories; use bind mounts for indirection."],"tags":["paths","symlink","security","validation"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}