unslothai/unsloth · warning · ValueError

dataset path must be relative or under a dataset root: {raw!

Error message

dataset path must be relative or under a dataset root: {raw!r}

What it means

Raised by resolve_dataset_path when the input is an absolute path that is not contained in any of the accepted roots (datasets_root, dataset_uploads_root, recipe_datasets_root, checked via realpath+commonpath). Absolute paths are only honored when they already live under a managed dataset root; everything else — /etc/passwd, /home/user/data — is refused. Relative paths and the 'uploads/'/'recipes' virtual prefixes are handled by later branches.

Source

Thrown at studio/backend/hub/utils/paths.py:407

def resolve_dataset_path(path_value: str) -> Path:
    raw = str(path_value or "").strip()
    if "\x00" in raw:
        raise ValueError("dataset path may not contain null bytes")
    # Normalize first so Windows/UNC and backslash paths resolve like the rest of the Hub path
    # layer, and a backslashed '..' is caught by the traversal guard below.
    normalized = normalize_path(raw)
    path = Path(normalized).expanduser()
    if ".." in path.parts:
        raise ValueError(f"dataset path may not contain '..' segments: {raw!r}")
    if path.is_absolute():
        for root in (datasets_root(), dataset_uploads_root(), recipe_datasets_root()):
            try:
                _assert_contained(path, root)
                return path
            except ValueError:
                continue
        raise ValueError(f"dataset path must be relative or under a dataset root: {raw!r}")

    parts = [part for part in Path(normalized).parts if part not in ("", ".")]
    if parts[:2] == ["assets", "datasets"]:
        parts = parts[2:]
    if parts and parts[0] == "uploads":
        cleaned = Path(*parts[1:]) if len(parts) > 1 else Path()
        return dataset_uploads_root() / cleaned
    if parts and parts[0] == "recipes":
        cleaned = Path(*parts[1:]) if len(parts) > 1 else Path()
        return recipe_datasets_root() / cleaned

    cleaned = Path(*parts) if parts else Path()
    candidates = [
        dataset_uploads_root() / cleaned,
        recipe_datasets_root() / cleaned,
        datasets_root() / cleaned,
        dataset_uploads_root() / cleaned.name,
        recipe_datasets_root() / cleaned.name,

View on GitHub (pinned to 203007d190)

Solutions

  1. Use a relative path or the logical prefixes: 'mydata.csv', 'uploads/...', or 'recipes/...'.
  2. If an absolute path is required, place the data under one of the dataset roots (or reconfigure the root to cover the location) and ensure symlinks resolve inside it.
  3. Check for symlink escape: `realpath <path>` must start with one of the configured dataset roots.

Example fix

# before
resolve_dataset_path('/home/alice/my.csv')
# after
resolve_dataset_path('my.csv')   # resolved under datasets_root()
Defensive patterns

Strategy: validation

Validate before calling

from hub.utils.paths import datasets_root, dataset_uploads_root, recipe_datasets_root

def absolute_dataset_path_ok(path: str) -> bool:
    p = Path(path).expanduser()
    if not p.is_absolute():
        return True
    pr = Path(os.path.realpath(p))
    return any(
        os.path.commonpath([pr, os.path.realpath(str(r))]) == os.path.realpath(str(r))
        for r in (datasets_root(), dataset_uploads_root(), recipe_datasets_root())
    )

Try / catch

try:
    p = resolve_dataset_path(value)
except ValueError as e:
    if "relative or under a dataset root" in str(e):
        return bad_request("use a relative dataset path like 'uploads/file.csv'")

Prevention

When it happens

Trigger: Calling a dataset API with '/home/alice/my.csv' (outside all roots) or '/var/data/d.csv'; also fires when a path that looks contained is actually a symlink whose realpath resolves outside every root (commonpath uses realpath).

Common situations: Users pasting local absolute paths where a logical dataset-relative path is expected; moved/renamed dataset roots so previously-valid absolute paths no longer resolve inside; symlinked data dirs that point elsewhere.

Related errors


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