{"record":{"id":"b7ab1edb0ba2208f","repo":"unslothai/unsloth","slug":"native-path-is-no-longer-a-directory","errorCode":null,"errorMessage":"Native path is no longer a directory.","messagePattern":"Native path is no longer a directory\\.","errorType":"validation","errorClass":"NativePathLeaseError","httpStatus":400,"severity":"error","filePath":"studio/backend/utils/native_path_leases.py","lineNumber":357,"sourceCode":"        if \"\\x00\" in str(raw):\n            raise NativePathLeaseError(\"Native path grant contains invalid characters.\")\n\n\ndef _validate_current_stat(\n    grant: NativePathGrant, identity_options: tuple[tuple[int, int], ...]\n) -> tuple[int, int] | None:\n    try:\n        st = os.lstat(grant.canonical_path)\n    except OSError as exc:\n        raise NativePathLeaseError(\"Native path is no longer accessible.\") from exc\n    if _stat_module.S_ISLNK(st.st_mode):\n        raise NativePathLeaseError(\"Native path is no longer a regular file.\")\n    if grant.path_type == \"file\":\n        if not _stat_module.S_ISREG(st.st_mode):\n            raise NativePathLeaseError(\"Native path is no longer a regular file.\")\n    elif grant.path_type == \"directory\":\n        if not _stat_module.S_ISDIR(st.st_mode):\n            raise NativePathLeaseError(\"Native path is no longer a directory.\")\n    else:\n        raise NativePathLeaseError(\"Native path grant has an unsupported path type.\")\n\n    if grant.size_bytes is not None and st.st_size != grant.size_bytes:\n        raise NativePathLeaseError(\"Native path changed after it was selected.\")\n    current_modified_ms = int(st.st_mtime_ns // 1_000_000)\n    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:","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/native_path_leases.py#L339-L375","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\n$ stat -c '%F' project\ngregular file    # was a folder at selection time\n\n# after\n$ mv project project.zip && mkdir project && unzip project.zip -d project\n# re-select 'project' folder, resubmit","handlingStrategy":"validation","validationCode":"import os, stat\n\ndef path_is_directory(path: str) -> bool:\n    try:\n        return stat.S_ISDIR(os.lstat(path).st_mode)\n    except OSError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    grant = verify_native_path_lease(lease, operation='read', expected_path_type='directory')\nexcept NativePathLeaseError as exc:\n    if 'no longer a directory' in str(exc):\n        return respond(409, 'Selected folder no longer exists as a folder; re-select.')\n    raise","preventionTips":["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."],"tags":["native-path-lease","filesystem","type-mismatch","directory"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}