unslothai/unsloth · error · RuntimeError

Linked folder is unavailable

Error message

Linked folder is unavailable

What it means

RuntimeError raised by _root_identity when os.lstat on an already-registered linked folder raises OSError — the folder has disappeared or become unreachable since registration. This runs during sync operations on persisted links (not initial validation, which raises ValueError), so the distinction signals drift from a previously valid state: unmounted drive, deleted folder, or revoked network share.

Source

Thrown at studio/backend/core/rag/folder_sync.py:169

    if is_local_filesystem_root(normalized):
        raise ValueError("The filesystem root cannot be registered")
    try:
        if Path(normalized) == Path.home().resolve():
            raise ValueError("The entire home folder cannot be registered")
    except RuntimeError:
        pass
    if contains_sensitive_path_component(normalized):
        raise ValueError("Credential or configuration directories are not allowed")
    if is_denied_system_path(normalized):
        raise ValueError("System directories are not allowed")
    return normalized


def _root_identity(root: str) -> tuple[int, int]:
    try:
        root_stat = os.lstat(root)
    except OSError as exc:
        raise RuntimeError("Linked folder is unavailable") from exc
    if stat.S_ISLNK(root_stat.st_mode) or not stat.S_ISDIR(root_stat.st_mode):
        raise RuntimeError("Linked folder is no longer a regular directory")
    if os.path.normcase(os.path.realpath(root)) != os.path.normcase(root):
        raise RuntimeError("Linked folder no longer resolves to its registered path")
    return root_stat.st_dev, root_stat.st_ino


def _store_identity(identity: tuple[int, int]) -> tuple[int | str, int | str]:
    return tuple(value if value <= _SQLITE_INTEGER_MAX else f"x{value:x}" for value in identity)


def _file_identity(metadata: dict) -> tuple[int | str, int | str]:
    return _store_identity((metadata["device"], metadata["inode"]))


def _load_identity(device_id: int | str, file_id: int | str) -> tuple[int, int]:
    def load(value: int | str) -> int:
        return (

View on GitHub (pinned to 203007d190)

Solutions

  1. Remount or restore the missing volume, then retry the sync.
  2. If the folder is gone permanently, unregister (delete) the linked-folder record from RAG settings so sync stops failing.
  3. Catch this RuntimeError per-folder in sync loops and skip/quarantine the dead link instead of aborting the whole sync.
  4. Prefer stable, always-mounted paths for registered folders.

Example fix

# before
for link in registered_folders():
    sync_folder(link)  # one dead volume aborts the loop

# after
for link in registered_folders():
    try:
        sync_folder(link)
    except RuntimeError as e:
        if 'unavailable' not in str(e):
            raise
        logger.warning('skipping unavailable folder %s', link)
        mark_quarantined(link)
Defensive patterns

Strategy: try-catch

Validate before calling

import os

def folder_still_available(root: str) -> bool:
    try:
        os.lstat(root)
        return True
    except OSError:
        return False

# before each sync:
# if not folder_still_available(link.path): skip_and_quarantine(link)

Try / catch

for link in registered_folders():
    try:
        sync(link)
    except RuntimeError as e:
        if "Linked folder is unavailable" not in str(e):
            raise
        logger.warning("folder %s unavailable; skipping", link.path)
        quarantine(link)  # keep syncing the rest

Prevention

When it happens

Trigger: A periodic sync iterating registered links when one folder's volume is unmounted (USB unplugged, NFS share down) or the folder was deleted; container restart where a host bind-mount source is gone.

Common situations: Removable media registered then removed; laptop sleep/wake dropping network mounts; folders deleted by backup/cleanup scripts; docker volumes removed while the DB still references them.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/7aa2d248b1c0c854. Report an issue: GitHub.