unslothai/unsloth · error · ValueError

local cache path contains invalid characters

Error message

local cache path contains invalid characters

What it means

Raised by the _check_cache_local_path field validator when the path string contains a NUL byte (\x00). NUL cannot appear in a valid filesystem path on POSIX or Windows and would truncate the path at the OS boundary or raise EINVAL, so the validator rejects it with a clear message. This also serves as a payload-injection guard.

Source

Thrown at studio/backend/models/training.py:270

        return v

    @field_validator(
        "model_local_path",
        "dataset_local_path",
        "model_snapshot_path",
        "dataset_snapshot_path",
    )
    @classmethod
    def _check_cache_local_path(cls, v: Optional[str]) -> Optional[str]:
        if v is None:
            return v
        v = v.strip()
        if not v:
            return None
        if len(v) > 4096:
            raise ValueError("local cache path is too long (max 4096 chars)")
        if "\x00" in v:
            raise ValueError("local cache path contains invalid characters")
        if ".." in Path(v).parts or ".." in PureWindowsPath(v).parts:
            raise ValueError("local cache path must not contain '..' segments")
        return v

    @field_validator("train_split", "eval_split")
    @classmethod
    def _check_split_name(cls, v: Optional[str]) -> Optional[str]:
        if v is None:
            return v
        v = v.strip()
        if not v:
            return None
        if len(v) > MAX_HF_DATASET_OPTION_LENGTH:
            raise ValueError(f"split name is too long (max {MAX_HF_DATASET_OPTION_LENGTH} chars)")
        if not valid_hf_dataset_split_instruction(v):
            raise ValueError("split name contains invalid characters")
        return v

View on GitHub (pinned to 203007d190)

Solutions

  1. Remove the NUL byte from the value and investigate how it got into a path field.
  2. If reading from a socket/file, use proper length-prefixed or JSON framing instead of NUL-terminated reads.
  3. Add a client-side check: if ('\x00' in path) reject before submit.

Example fix

# before
path = raw_bytes.decode("utf-8", "replace")  # may contain \x00
# after
path = raw_bytes.decode("utf-8").replace("\x00", "")  # or reject outright
Defensive patterns

Strategy: type-guard

Validate before calling

def paths_nul_free(body: dict) -> bool:
    return all("\x00" not in (body.get(f) or "") for f in PATH_FIELDS)

Type guard

function nulFree(p: string | undefined): boolean {
  return !p?.includes('\x00');
}

Prevention

When it happens

Trigger: POST a training start request with any of the four cache-path fields containing a literal \x00 byte, e.g. from deserializing binary data into a string field or a truncated network read.

Common situations: Binary data mistakenly decoded into a path field; socket/HTTP payloads cut at a NUL; test fuzzers generating random bytes; data pipelines passing bytes where str is expected.

Understand the failure class

Related errors


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