unslothai/unsloth · error · NativePathLeaseError

Native path grant was already used.

Error message

Native path grant was already used.

What it means

The grant's nonce is already recorded in the process-wide _USED_NONCES replay cache, so this exact grant was redeemed before. Nonces are single-use: once verify_native_path_lease() accepts a grant, its nonce is stored until expiry, making byte-identical replay impossible. This is an anti-replay control for capabilities that are otherwise short-lived and bearer-style.

Source

Thrown at studio/backend/utils/native_path_leases.py:382

    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:
    now_ms = int(time.time() * 1000)
    with _REPLAY_LOCK:
        for key, expiry in list(_USED_NONCES.items()):
            if expiry <= now_ms:
                _USED_NONCES.pop(key, None)
        if nonce in _USED_NONCES:
            raise NativePathLeaseError("Native path grant was already used.")
        _USED_NONCES[nonce] = expires_at_ms


def _remember_native_path_for_redaction(path: str, display_label: str) -> None:
    with _REDACTION_LOCK:
        _NATIVE_PATH_LABELS[path] = display_label
        if len(_NATIVE_PATH_LABELS) > _MAX_NATIVE_PATH_LABELS:
            excess = len(_NATIVE_PATH_LABELS) - _MAX_NATIVE_PATH_LABELS
            for stale_path in list(_NATIVE_PATH_LABELS.keys())[:excess]:
                _NATIVE_PATH_LABELS.pop(stale_path, None)
        if path in _NATIVE_PATH_REDACTIONS:
            return
        _NATIVE_PATH_REDACTIONS.append(path)
        del _NATIVE_PATH_REDACTIONS[:-_MAX_NATIVE_PATH_REDACTIONS]


def _reject_network_or_device_path(path: Path) -> None:
    text = str(path)

View on GitHub (pinned to 203007d190)

Solutions

  1. Request a fresh grant (re-pick the file or call the grant-refresh flow) for every request; never cache and reuse a lease across calls.
  2. Make retries idempotent at a higher level: on this error, refresh the grant and retry once with the new lease.
  3. Check whether the first submission actually succeeded before retrying (query job status) to avoid duplicate work.
  4. Ensure concurrent workers each obtain their own grant instead of sharing one.

Example fix

# before
resp = api.post('/train', json={'lease': lease})   # retry on timeout reuses lease

# after
def submit(lease_getter):
    for attempt in range(2):
        try:
            return api.post('/train', json={'lease': lease_getter()})
        except NativePathLeaseError as e:
            if 'already used' not in str(e) or attempt:
                raise
Defensive patterns

Strategy: retry

Try / catch

try:
    grant = verify_native_path_lease(lease, operation='read')
except NativePathLeaseError as exc:
    if 'already used' in str(exc):
        lease = request_fresh_grant()   # nonces are single-use by design
        grant = verify_native_path_lease(lease, operation='read')
    else:
        raise

Prevention

When it happens

Trigger: Calling verify_native_path_lease() twice with the same lease string within its TTL: a frontend retrying a failed request after the grant was already consumed (nonce is consumed late in verification, so a failure after _consume_nonce still burns it); duplicate form submissions; a job queue retrying a task that carries the same grant; two concurrent requests sharing one grant.

Common situations: HTTP retry on network timeout where the first attempt actually succeeded; double-click/duplicate submission; retry logic in an SDK replaying the request body verbatim; load tests reusing captured grant strings.

Related errors


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