{"record":{"id":"0d8a23e61c5d4d50","repo":"unslothai/unsloth","slug":"native-path-grant-was-already-used","errorCode":null,"errorMessage":"Native path grant was already used.","messagePattern":"Native path grant was already used\\.","errorType":"exception","errorClass":"NativePathLeaseError","httpStatus":400,"severity":"error","filePath":"studio/backend/utils/native_path_leases.py","lineNumber":382,"sourceCode":"    if grant.modified_ms is not None and current_modified_ms != grant.modified_ms:\n        raise NativePathLeaseError(\"Native path changed after it was selected.\")\n    if grant.path_kind == \"document-folder\" and not identity_options:\n        raise NativePathLeaseError(\"Native path grant is missing its folder identity.\")\n    current_identity = (st.st_dev, st.st_ino)\n    expected_identity = _runtime_identity(identity_options)\n    if expected_identity is not None and current_identity != expected_identity:\n        raise NativePathLeaseError(\"Native path changed after it was selected.\")\n    return current_identity if expected_identity is not None else None\n\n\ndef _consume_nonce(nonce: str, expires_at_ms: int) -> None:\n    now_ms = int(time.time() * 1000)\n    with _REPLAY_LOCK:\n        for key, expiry in list(_USED_NONCES.items()):\n            if expiry <= now_ms:\n                _USED_NONCES.pop(key, None)\n        if nonce in _USED_NONCES:\n            raise NativePathLeaseError(\"Native path grant was already used.\")\n        _USED_NONCES[nonce] = expires_at_ms\n\n\ndef _remember_native_path_for_redaction(path: str, display_label: str) -> None:\n    with _REDACTION_LOCK:\n        _NATIVE_PATH_LABELS[path] = display_label\n        if len(_NATIVE_PATH_LABELS) > _MAX_NATIVE_PATH_LABELS:\n            excess = len(_NATIVE_PATH_LABELS) - _MAX_NATIVE_PATH_LABELS\n            for stale_path in list(_NATIVE_PATH_LABELS.keys())[:excess]:\n                _NATIVE_PATH_LABELS.pop(stale_path, None)\n        if path in _NATIVE_PATH_REDACTIONS:\n            return\n        _NATIVE_PATH_REDACTIONS.append(path)\n        del _NATIVE_PATH_REDACTIONS[:-_MAX_NATIVE_PATH_REDACTIONS]\n\n\ndef _reject_network_or_device_path(path: Path) -> None:\n    text = str(path)","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/native_path_leases.py#L364-L400","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Make retries idempotent at a higher level: on this error, refresh the grant and retry once with the new lease.","Check whether the first submission actually succeeded before retrying (query job status) to avoid duplicate work.","Ensure concurrent workers each obtain their own grant instead of sharing one."],"exampleFix":"# before\nresp = api.post('/train', json={'lease': lease})   # retry on timeout reuses lease\n\n# after\ndef submit(lease_getter):\n    for attempt in range(2):\n        try:\n            return api.post('/train', json={'lease': lease_getter()})\n        except NativePathLeaseError as e:\n            if 'already used' not in str(e) or attempt:\n                raise","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    grant = verify_native_path_lease(lease, operation='read')\nexcept NativePathLeaseError as exc:\n    if 'already used' in str(exc):\n        lease = request_fresh_grant()   # nonces are single-use by design\n        grant = verify_native_path_lease(lease, operation='read')\n    else:\n        raise","preventionTips":["One grant per request: fetch a fresh lease for every API call, never cache it.","Before retrying a timed-out request, check whether the first attempt succeeded (nonce may be burned).","Give concurrent workers their own grants instead of sharing one lease string."],"tags":["native-path-lease","replay","nonce","retry"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}