unslothai/unsloth · error · HTTPException
Could not read {os.path.basename(str(current))}
Error message
Could not read {os.path.basename(str(current))} What it means
Raised as a 500 by _match_browse_child when iterdir() on an intermediate directory fails with a non-permission OSError while the backend walks toward the requested browse path. The full exception is logged with exc_info; the client gets a generic basename-only message so raw OS errors are not leaked.
Source
Thrown at studio/backend/routes/models.py:1644
if part == ".." or os.sep in part or (altsep and altsep in part):
return None
return parts
def _match_browse_child(current: Path, name: str) -> Optional[Path]:
"""Return the immediate child named ``name`` under ``current``."""
try:
for child in current.iterdir():
if child.name == name:
return child
except PermissionError:
raise HTTPException(
status_code = 403,
detail = f"Permission denied reading {current.name}",
) from None
except OSError as exc:
logger.warning("browse-folders: could not read %s: %s", current, exc, exc_info = True)
raise HTTPException(
status_code = 500,
detail = f"Could not read {os.path.basename(str(current))}",
) from exc
return None
def _resolve_browse_target(path: Optional[str], allowed_roots: list[Path]) -> Path:
"""Resolve a requested browse path by walking from trusted allowlist roots."""
from storage.studio_db import (
contains_sensitive_path_component,
is_denied_system_path,
)
requested_path = _normalize_browse_request_path(path)
resolved_roots: list[Path] = []
seen_roots: set[str] = set()
for root in sorted(allowed_roots, key = lambda p: len(str(p)), reverse = True):
try:View on GitHub (pinned to 203007d190)
Solutions
- Check the backend logs — the warning line includes the exact directory and OS error.
- Restore the mount/share (reconnect the drive, remount NFS/SMB) and retry.
- If a directory was removed, refresh the front-end tree from the allowlist root and re-navigate.
- Register a scan folder closer to the data so the walk avoids the failing intermediate directory.
Defensive patterns
Strategy: fallback
Validate before calling
import os
def mount_alive(d: str) -> bool:
try:
os.statvfs(d); return True
except OSError:
return False
if not mount_alive(models_dir):
show_user('Storage for this folder is offline — reconnect it, then retry.') Try / catch
try:
entries = browse(path)
except HTTPError as e:
if e.response.status_code == 500 and 'Could not read' in e.response.json()['detail']:
return fallback_to_cached_entries(path) # show last-known tree, offer retry
raise Prevention
- Watch backend logs for 'browse-folders: could not read' — it carries the real errno.
- Use stable local storage for model directories; avoid mounts that sleep/disconnect.
- Cache the last successful listing in the UI so an offline share degrades gracefully.
When it happens
Trigger: Browsing a path that traverses an unresponsive network share, a disconnected mapped drive, a stale NFS mount, or a directory deleted mid-walk; ENOENT/EIO/EMFILE-class errors during the component-by-component walk.
Common situations: Mapped drive disconnected on Windows; NFS/SMB server down or timing out; antivirus or filesystem corruption causing EIO; race between directory listing and deletion.
Related errors
- Permission denied reading {current.name}
- Could not read {os.path.basename(str(target))}
- Path does not exist: {os.path.basename(requested_path)}
- Invalid path
- Permission denied reading {os.path.basename(str(target))}
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/980fec905bab297f.
Report an issue: GitHub.