unslothai/unsloth · error · NativePathLeaseError
Native path grant no longer resolves to the selected path.
Error message
Native path grant no longer resolves to the selected path.
What it means
After strict resolution, the resolved path is not the same file as the originally signed path (samefile() fails and normalized string comparison fails too). The signed canonical_path must resolve to itself; if resolution lands on a different inode/path, the grant no longer names the file the user actually selected.
Source
Thrown at studio/backend/utils/native_path_leases.py:199
payload = _decode_payload(payload_b64)
_validate_payload(payload, operation = operation, expected_kind = expected_kind)
path = Path(str(payload["canonical_path"]))
_reject_network_or_device_path(path)
try:
signed_lstat = os.lstat(path)
except OSError as exc:
raise NativePathLeaseError("Native path is no longer accessible.") from exc
if _stat_module.S_ISLNK(signed_lstat.st_mode):
raise NativePathLeaseError("Native path is no longer a regular file.")
try:
resolved = path.resolve(strict = True)
except OSError as exc:
raise NativePathLeaseError("Native path is no longer accessible.") from exc
_reject_network_or_device_path(resolved)
if not _same_native_path(resolved, path):
raise NativePathLeaseError("Native path grant no longer resolves to the selected path.")
identity_options = _identity_options(payload)
grant = NativePathGrant(
operation = str(payload["operation"]),
canonical_path = resolved,
path_kind = str(payload["path_kind"]),
path_type = str(payload["path_type"]),
source_kind = str(payload["source_kind"]),
token_id_hash = str(payload["token_id_hash"]),
display_label = str(payload.get("display_label") or resolved.name),
expires_at_ms = _required_int(payload, "expires_at_ms"),
size_bytes = _optional_int(payload.get("size_bytes")),
modified_ms = _optional_int(payload.get("modified_ms")),
device_id = identity_options[0][0] if identity_options else None,
file_id = identity_options[0][1] if identity_options else None,
)
if expected_path_type and grant.path_type != expected_path_type:View on GitHub (pinned to 203007d190)
Solutions
- Re-select the file so the grant is issued from the same environment/view that verifies it.
- Ensure the backend and the Tauri shell see the same mount and symlink layout (don't run one inside a container and the other on the host).
- If you maintain the Rust signing side, confirm it signs the fully resolved canonical path, matching pathlib's resolve(strict=True) semantics.
- Avoid replacing the selected file (copy-in-place instead of delete+rename) while its grant is outstanding.
Defensive patterns
Strategy: try-catch
Try / catch
try:
grant = verify_native_path_lease(lease, operation=OP)
except NativePathLeaseError as exc:
if "no longer resolves" in str(exc):
return error_response(409, "File identity changed; please re-select the file.")
raise Prevention
- Run signer and backend under the same mount namespace/user view.
- Sign fully resolved canonical paths on the Rust side.
- Prefer in-place edits over delete+rename for files with outstanding grants.
When it happens
Trigger: The path involves symlinks or bind mounts such that resolving yields a different filesystem identity than the signed path; the file was replaced (deleted + recreated) between signing and verification so inode identity changed; case-insensitive filesystems where the signed path's casing no longer matches the on-disk entry; or a mount was remounted over the directory.
Common situations: Selecting files through symlinked home directories (e.g. /tmp -> /private/tmp on macOS) where the Rust signer and Python resolver disagree on canonical form; file-replacement by editors with atomic-write patterns (new inode); mount namespace differences between the Tauri shell and a containerized backend.
Related errors
- GGUF conversion produced a symlink, refusing to relocate it:
- Linked folder is no longer a regular directory
- Linked folder no longer resolves to its registered path
- Models folder path is not a directory: {path}
- Invalid block_id: outside upload root
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/cc013e6c16e5ae5f.
Report an issue: GitHub.