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

  1. Remove NUL bytes from the path on the client side (they are never legitimate).
  2. If this appears in logs without an obvious client, investigate whether a scanner or proxy is mutating payloads.
  3. 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

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


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