unslothai/unsloth · error · ValueError
dataset path may not contain '..' segments: {raw!r}
Error message
dataset path may not contain '..' segments: {raw!r} What it means
Raised by resolve_dataset_path() when the expanded path contains a '..' segment. The resolver deliberately blocks parent-directory segments so a caller cannot escape the managed dataset storage roots; this is a path-traversal guard, not an incidental failure.
Source
Thrown at studio/backend/utils/paths/storage_roots.py:502
strip_prefixes = ("exports",),
)
def resolve_tensorboard_dir(path_value: str | None = None) -> Path:
return resolve_under_root(
path_value,
root = tensorboard_root(),
strip_prefixes = ("runs", "tensorboard"),
)
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")
path = Path(raw).expanduser()
if ".." in path.parts:
raise ValueError(f"dataset path may not contain '..' segments: {raw!r}")
if path.is_absolute():
for root_fn in (datasets_root, dataset_uploads_root, recipe_datasets_root):
try:
_assert_contained(path, root_fn())
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(path_value).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() / cleanedView on GitHub (pinned to 203007d190)
Solutions
- Normalize the path client-side before sending: resolve '..' against a known base so no parent segments remain (e.g. posixpath.normpath on a sandboxed base).
- Reject the request with a 400 and surface 'paths may not contain ..' to the user instead of retrying.
- If the user genuinely meant a sibling dataset, send the canonical path relative to the dataset root without '..' segments.
Example fix
# before
resolve_dataset_path(request.args['path']) # '../../etc/passwd'
# after
import posixpath
raw = request.args['path']
if '..' in posixpath.normpath(raw).split('/') and raw.startswith('..'):
abort(400, 'dataset path may not contain .. segments')
resolve_dataset_path(raw) Defensive patterns
Strategy: validation
Validate before calling
from pathlib import PurePosixPath
def has_parent_segments(p: str) -> bool:
return '..' in PurePosixPath(p.replace('\\', '/')).parts
if has_parent_segments(user_path):
raise HTTPBadRequest('dataset path may not contain .. segments') Type guard
def is_safe_relative_dataset_path(p: str) -> bool:
parts = PurePosixPath(p.replace('\\', '/')).parts
return bool(p) and '\x00' not in p and '..' not in parts Try / catch
try:
path = resolve_dataset_path(raw)
except ValueError as e:
if "'..' segments" in str(e):
return bad_request('invalid dataset path') # never retry; it is malicious or a client bug
raise Prevention
- Always send dataset paths relative to a known root; never let clients type free-form paths with '..'.
- Mirror the '..' rejection in frontend validation so the error never reaches the backend.
When it happens
Trigger: Calling resolve_dataset_path() with values like '../secrets.env', 'datasets/../../etc/passwd', or 'a/../b' — note the check runs on Path(raw).expanduser().parts, so a '~' that expands to a path containing '..' also trips it. Both relative and absolute inputs are checked before root containment is evaluated.
Common situations: Frontends composing dataset paths from user-typed text, URL parameters carrying relative paths, or migrations importing legacy paths that used '..' for brevity. Crafted payloads attempting directory traversal through a dataset upload/download endpoint.
Related errors
- dataset path may not contain null bytes
- dataset path may not contain '..' segments: {raw!r}
- save_directory may not contain null bytes
- save_directory may not contain '..' segments
- hf_dataset must not contain '..'
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/a56881ba88aaa22f.
Report an issue: GitHub.