unslothai/unsloth · error · NativePathLeaseError
Native path is no longer a directory.
Error message
Native path is no longer a directory.
What it means
The grant declares path_type "directory" but the object at canonical_path is no longer a directory (S_ISDIR false). _validate_current_stat() verifies that the on-disk type still matches the signed path_type before any native directory operation proceeds. The lease is invalidated because the granted capability no longer corresponds to a real directory.
Source
Thrown at studio/backend/utils/native_path_leases.py:357
if "\x00" in str(raw):
raise NativePathLeaseError("Native path grant contains invalid characters.")
def _validate_current_stat(
grant: NativePathGrant, identity_options: tuple[tuple[int, int], ...]
) -> tuple[int, int] | None:
try:
st = os.lstat(grant.canonical_path)
except OSError as exc:
raise NativePathLeaseError("Native path is no longer accessible.") from exc
if _stat_module.S_ISLNK(st.st_mode):
raise NativePathLeaseError("Native path is no longer a regular file.")
if grant.path_type == "file":
if not _stat_module.S_ISREG(st.st_mode):
raise NativePathLeaseError("Native path is no longer a regular file.")
elif grant.path_type == "directory":
if not _stat_module.S_ISDIR(st.st_mode):
raise NativePathLeaseError("Native path is no longer a directory.")
else:
raise NativePathLeaseError("Native path grant has an unsupported path type.")
if grant.size_bytes is not None and st.st_size != grant.size_bytes:
raise NativePathLeaseError("Native path changed after it was selected.")
current_modified_ms = int(st.st_mtime_ns // 1_000_000)
if grant.modified_ms is not None and current_modified_ms != grant.modified_ms:
raise NativePathLeaseError("Native path changed after it was selected.")
if grant.path_kind == "document-folder" and not identity_options:
raise NativePathLeaseError("Native path grant is missing its folder identity.")
current_identity = (st.st_dev, st.st_ino)
expected_identity = _runtime_identity(identity_options)
if expected_identity is not None and current_identity != expected_identity:
raise NativePathLeaseError("Native path changed after it was selected.")
return current_identity if expected_identity is not None else None
def _consume_nonce(nonce: str, expires_at_ms: int) -> None:View on GitHub (pinned to 203007d190)
Solutions
- stat <path> to see the current object type.
- Restore the directory (recreate it, or undo the rename that replaced it).
- Re-select the folder in the native picker to mint a new grant and resubmit.
Example fix
# before $ stat -c '%F' project gregular file # was a folder at selection time # after $ mv project project.zip && mkdir project && unzip project.zip -d project # re-select 'project' folder, resubmit
Defensive patterns
Strategy: validation
Validate before calling
import os, stat
def path_is_directory(path: str) -> bool:
try:
return stat.S_ISDIR(os.lstat(path).st_mode)
except OSError:
return False Try / catch
try:
grant = verify_native_path_lease(lease, operation='read', expected_path_type='directory')
except NativePathLeaseError as exc:
if 'no longer a directory' in str(exc):
return respond(409, 'Selected folder no longer exists as a folder; re-select.')
raise Prevention
- Don't rename/replace selected folders while a job is pending.
- Re-select the folder after reorganizing directory layout.
- Pass expected_path_type='directory' so wrong-type grants fail fast with a clear message.
When it happens
Trigger: verify_native_path_lease() with grant.path_type == 'directory' where lstat shows a regular file, symlink, or other non-directory object: user picked a folder, then deleted it and a file with the same name appeared; the folder was replaced during a sync/move operation.
Common situations: Folder replaced by a file of the same name (e.g. datasets/ turned into datasets.zip extracted oddly); a rename race during job submission; user reorganized directories while a queued job waited.
Related errors
- Native folder grant has no stable identity.
- Native path changed after it was selected.
- Execution artifacts are no longer available.
- Execution artifact path is not a dataset folder.
- GGUF conversion produced a symlink, refusing to relocate it:
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/b7ab1edb0ba2208f.
Report an issue: GitHub.