unslothai/unsloth · error · NativePathLeaseError
Native path grant has expired.
Error message
Native path grant has expired.
What it means
The signed native path grant's expires_at_ms is in the past relative to the backend's current clock, so the lease is no longer honored. Grants are short-lived capabilities bound to a file the user just picked in the desktop UI; the backend refuses to read a native path once the lease window has closed. This is a freshness guarantee, not a permanent entitlement. The check uses the backend process clock, so clock skew between the Tauri shell and the backend also matters.
Source
Thrown at studio/backend/utils/native_path_leases.py:332
"expires_at_ms",
"nonce",
)
missing = [key for key in required if key not in payload]
if missing:
raise NativePathLeaseError("Native path grant payload is missing required fields.")
if _required_int(payload, "version") != 1:
raise NativePathLeaseError("Native path grant version is unsupported.")
if payload["operation"] != operation:
raise NativePathLeaseError("Native path grant operation is invalid.")
if expected_kind and payload["path_kind"] != expected_kind:
raise NativePathLeaseError("Native path grant kind is invalid.")
now_ms = int(time.time() * 1000)
issued_at_ms = _required_int(payload, "issued_at_ms")
expires_at_ms = _required_int(payload, "expires_at_ms")
if issued_at_ms >= expires_at_ms:
raise NativePathLeaseError("Native path grant timestamps are inconsistent.")
if expires_at_ms <= now_ms:
raise NativePathLeaseError("Native path grant has expired.")
if issued_at_ms > now_ms + 30_000:
raise NativePathLeaseError("Native path grant issue time is invalid.")
for key in ("canonical_path", "nonce", "token_id_hash", "display_label"):
raw = payload.get(key)
if raw is None:
continue
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):View on GitHub (pinned to 203007d190)
Solutions
- Request a fresh grant: re-trigger the native file selection (or the frontend's grant-refresh endpoint) and resend the request immediately.
- Shorten the gap between selection and submission so the operation lands inside the grant TTL.
- If it reproduces consistently, compare the signer's clock and the backend's clock (date +%s%3N on both) and fix NTP/timezone or container clock skew.
- If a longer window is genuinely needed, raise the TTL in the Rust signer (and keep issued_at < expires).
Example fix
// before (frontend)
const lease = await pickNativeFile(path); // grant cached for the whole session
submitJob(lease); // fails hours later
// after
async function submitJob(path) {
const lease = await refreshNativeGrant(path); // fresh, short-lived grant
await api.post('/job', { lease });
} Defensive patterns
Strategy: retry
Validate before calling
import base64, json, time
def grant_still_valid(lease: str, skew_ms: int = 0) -> bool:
payload = json.loads(base64.urlsafe_b64decode(lease.split('.')[0] + '=='))
return int(payload['expires_at_ms']) > int(time.time() * 1000) + skew_ms Try / catch
try:
grant = verify_native_path_lease(lease, operation='read')
except NativePathLeaseError as exc:
if 'has expired' in str(exc):
lease = request_fresh_grant() # re-pick / refresh endpoint
grant = verify_native_path_lease(lease, operation='read')
else:
raise Prevention
- Submit the job immediately after file selection; do not cache leases across screens.
- Wrap long-running user flows with a grant-refresh step before the final API call.
- Verify signer and backend clocks agree (same host) to avoid false expiries.
When it happens
Trigger: verify_native_path_lease() is called with a lease whose expires_at_ms <= int(time.time()*1000). Typical when the user picked a file, then submitted the job minutes later; when the request was retried/queued past the TTL; or when the backend clock is ahead of the machine clock that signed the grant.
Common situations: Long dwell time on a form after a file-picker grant was issued; paginated/retried uploads replaying an old grant; a laptop resumed from sleep (clock jumped); NTP drift between processes or containers; debugging sessions where the grant was captured hours earlier.
Related errors
- Native path grant issue time is invalid.
- Native path grant timestamps are inconsistent.
- Native path grant is required.
- Dropped file could not be read.
- Native folder grant has no stable identity.
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/1431c9d80fb57df0.
Report an issue: GitHub.