unslothai/unsloth · error · ValueError
save_directory may not contain null bytes
Error message
save_directory may not contain null bytes
What it means
ValueError from _validate_save_directory when the path contains a NUL byte (\x00). NUL cannot appear in a real filesystem path on Linux/macOS and would cause OSError ('embedded null byte') at write time, so it is rejected at the validation boundary — it is also a classic path-injection probe.
Source
Thrown at studio/backend/models/export.py:20
# Copyright 2026-present the Unsloth AI Inc. team. All rights reserved. See /studio/LICENSE.AGPL-3.0
"""Pydantic schemas for Export API."""
from pathlib import Path, PureWindowsPath
from pydantic import BaseModel, Field, field_validator
from typing import List, Optional, Literal, Dict, Any, Union
def _validate_save_directory(value: str) -> str:
"""Validate save_directory — allows absolute paths (user may want a different drive)."""
if value is None:
raise ValueError("save_directory is required")
raw = str(value).strip()
if not raw:
raise ValueError("save_directory must not be empty")
if "\x00" in raw:
raise ValueError("save_directory may not contain null bytes")
if any(ch in raw for ch in ("\r", "\n")):
raise ValueError("save_directory may not contain control characters")
path = Path(raw).expanduser()
path_parts = (*path.parts, *PureWindowsPath(raw).parts, *raw.replace("\\", "/").split("/"))
if any(len(part) > 255 for part in path_parts if part not in ("", ".", "/", "\\")):
raise ValueError("save_directory path components must be <= 255 characters")
if (
".." in path.parts
or ".." in PureWindowsPath(raw).parts
or ".." in raw.replace("\\", "/").split("/")
):
raise ValueError("save_directory may not contain '..' segments")
return raw
class LoadCheckpointRequest(BaseModel):
"""Request for loading a checkpoint into the export backend."""
View on GitHub (pinned to 203007d190)
Solutions
- Remove NUL bytes from the path on the client side (they are never legitimate).
- If this appears in logs without an obvious client, investigate whether a scanner or proxy is mutating payloads.
- Reject or sanitize inputs that fail a printable-ASCII/UTF-8 sanity check before they reach the API.
Example fix
// before
{ "save_directory": "/tmp/\u0000export" }
// after
{ "save_directory": "/tmp/export" } Defensive patterns
Strategy: validation
Validate before calling
def save_directory_safe(payload: dict) -> bool:
v = payload.get("save_directory")
return isinstance(v, str) and "\x00" not in v Type guard
def is_null_free_path(v: str) -> bool:
return isinstance(v, str) and "\x00" not in v Prevention
- Sanitize user-supplied paths by rejecting non-printable characters before they reach the API.
- Treat NUL bytes in requests as malicious — alert on them, don't silently clean them.
- Validate decoded base64/URL-encoded payload segments before use.
When it happens
Trigger: Sending save_directory containing a literal \u0000, e.g. "/tmp/\x00evil" or a value deserialized from truncated binary input; fuzzing or security scanning of the export endpoint.
Common situations: Penetration tests / automated scanners probing path handling; corrupted client state or truncated base64 decoding producing control characters.
Related errors
- save_directory may not contain '..' segments
- save_directory may not contain control characters
- dataset path may not contain null bytes
- dataset path may not contain '..' segments: {raw!r}
- save_directory is required
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/638df2d562fa6be5.
Report an issue: GitHub.