unslothai/unsloth · error · HTTPException

Dataset '{cleaned}' not found.

Error message

Dataset '{cleaned}' not found.

What it means

HTTP 404 from _resolve_dataset_folder when must_exist=True and the cleaned dataset name does not exist as a directory under the Studio datasets root. The name was syntactically valid (passed _clean_diffusion_dataset_name); the folder simply is not there — deleted, never created, or created under a different name.

Source

Thrown at studio/backend/routes/training.py:3621

_MAX_CAPTION_CHARS = 2000


def _resolve_dataset_folder(name: str, *, must_exist: bool = True) -> Path:
    """Validate ``name`` (single component, no traversal) and resolve it under the Studio
    datasets root. 404 when a read target is missing."""
    from utils.paths import datasets_root

    cleaned = _clean_diffusion_dataset_name(name)
    root = datasets_root().resolve()
    folder = root / cleaned
    # Reject a symlinked dataset directory and prove the resolved folder stays under root: _safe_dataset_image_path only checks each image path, not the folder.
    if folder.is_symlink():
        raise HTTPException(
            status_code = 400,
            detail = f"Dataset '{cleaned}' must not be a symbolic link.",
        )
    if must_exist and not folder.is_dir():
        raise HTTPException(status_code = 404, detail = f"Dataset '{cleaned}' not found.")
    try:
        folder.resolve(strict = must_exist).relative_to(root)
    except (OSError, ValueError):
        raise HTTPException(
            status_code = 400,
            detail = f"Dataset '{cleaned}' escapes the Studio datasets directory.",
        )
    return folder


# Match diffusion's 4096px decoded-image limit.
_MAX_TRAINING_IMAGE_SIDE = 4096


def _validate_uploaded_training_image(path: Path, original_name: str) -> None:
    """Reject an uploaded training image whose decoded dimensions exceed the per-side limit.

    Reads only the header (never img.load()), so a small-payload / huge-dimension file is caught

View on GitHub (pinned to 203007d190)

Solutions

  1. Reload the dataset list (GET /diffusion/datasets) and use a current name.
  2. If the dataset was renamed on disk, rename it back or re-create it via upload/import and update your references.
  3. If it was deleted, re-import the example dataset or re-upload the files.

Example fix

// before
await api.get(`/training/diffusion/dataset/${name}/images`);

// after
const datasets = await api.get('/training/diffusion/datasets');
if (!datasets.some(d => d.name === name)) throw new Error(`Dataset '${name}' gone; refresh list`);
await api.get(`/training/diffusion/dataset/${name}/images`);
Defensive patterns

Strategy: validation

Validate before calling

from utils.paths import datasets_root

def dataset_exists(name: str) -> bool:
    folder = datasets_root() / name
    return folder.is_dir() and not folder.is_symlink()

Type guard

def is_dataset_not_found(exc: HTTPException) -> bool:
    return exc.status_code == 404 and 'not found' in (exc.detail or '')

Try / catch

try:
    folder = _resolve_dataset_folder(name, must_exist=True)
except HTTPException as e:
    if e.status_code == 404:
        return RefreshDatasetList()  # recover by re-enumerating
    raise

Prevention

When it happens

Trigger: Any dataset read route (list images, serve image, update caption, delete image, dataset summary) with a name that has no matching directory. Typical: GET /training/diffusion/dataset/old-name/image/cat.png after the dataset was deleted or renamed, or a stale UI tab holding an old dataset ID.

Common situations: Dataset deleted in another browser tab while a labeling grid stayed open; renaming a dataset out-of-band (shell mv) so the old name 404s; fresh installs referencing a dataset that was never imported; typos in scripted API calls.

Related errors


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