{"record":{"id":"14b7a9fec38afbb9","repo":"unslothai/unsloth","slug":"invalid-path","errorCode":null,"errorMessage":"Invalid path","messagePattern":"Invalid path","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"studio/backend/routes/models.py","lineNumber":1695,"sourceCode":"        current = root\n        for part in parts:\n            child = _match_browse_child(current, part)\n            if child is None:\n                raise HTTPException(\n                    status_code = 404,\n                    detail = f\"Path does not exist: {os.path.basename(requested_path)}\",\n                )\n            try:\n                resolved_child = child.resolve()\n            except OSError as exc:\n                logger.warning(\n                    \"browse-folders: invalid path component %r under %s: %s\",\n                    part,\n                    current,\n                    exc,\n                    exc_info = True,\n                )\n                raise HTTPException(\n                    status_code = 400,\n                    detail = \"Invalid path\",\n                ) from exc\n            if not _is_path_inside_allowlist(resolved_child, resolved_roots):\n                raise HTTPException(\n                    status_code = 403,\n                    detail = (\n                        \"Path is not in the browseable allowlist. Register it via \"\n                        \"POST /api/models/scan-folders first, or pick a directory \"\n                        \"under your home folder.\"\n                    ),\n                )\n            if contains_sensitive_path_component(str(resolved_child)):\n                raise HTTPException(\n                    status_code = 403,\n                    detail = \"Credential or configuration directories are not browseable.\",\n                )\n            if is_denied_system_path(str(resolved_child)):","sourceCodeStart":1677,"sourceCodeEnd":1713,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/routes/models.py#L1677-L1713","documentation":"Raised as a 400 by _resolve_browse_target when Path.resolve() on a matched child raises an OSError — the filesystem itself refused to canonicalize the component (e.g. too many symlinks, name too long, I/O error). The warning log names the component and parent directory; the client sees only the generic 'Invalid path'.","triggerScenarios":"Browsing a path containing a symlink loop (ELOOP), a component exceeding NAME_MAX, or resolve() hitting an I/O error on a failing disk/mount.","commonSituations":"Cyclic symlinks inside a models directory; extremely long auto-generated folder names; a flaky external drive returning errors during path resolution.","solutions":["Inspect the backend log line 'invalid path component' to identify which segment failed.","Break symlink cycles (find . -type l -xtype l) or rename over-length components.","If the mount is failing, remount or fsck the volume and retry browsing."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import os\n\ndef resolvable(path: str) -> bool:\n    try:\n        os.path.realpath(path)\n        return True\n    except OSError:\n        return False\n\nif not resolvable(models_dir):\n    raise ValueError('path cannot be resolved — check for symlink loops or over-long names')","typeGuard":null,"tryCatchPattern":"try:\n    entries = browse(path)\nexcept HTTPError as e:\n    if e.response.status_code == 400 and e.response.json()['detail'] == 'Invalid path':\n        show_user('That folder cannot be opened (bad symlink or invalid name). Pick another location.')\n    else: raise","preventionTips":["Avoid symlink loops when organizing model folders.","Check the backend log for 'invalid path component' to find the exact failing segment.","Prefer plain directories over deep symlink chains for model storage."],"tags":["filesystem","os-error","symlink","browse","path-resolution"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}