unslothai/unsloth · error · NativePathLeaseError
Native path grant has an unsupported file type.
Error message
Native path grant has an unsupported file type.
What it means
The caller passed allowed_suffixes and the resolved path's extension (lowercased) is not in that set. This is an extension-level file-type gate applied after signature verification — e.g. a GGUF import endpoint passes allowed_suffixes=('.gguf',) so a signed-but-wrong file type is rejected before any read.
Source
Thrown at studio/backend/utils/native_path_leases.py:221
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:
raise NativePathLeaseError("Native path grant has the wrong path type.")
suffixes = tuple(s.lower() for s in (allowed_suffixes or ()))
if suffixes and resolved.suffix.lower() not in suffixes:
raise NativePathLeaseError("Native path grant has an unsupported file type.")
current_identity = _validate_current_stat(grant, identity_options)
if current_identity is not None:
grant = replace(grant, device_id = current_identity[0], file_id = current_identity[1])
_consume_nonce(str(payload["nonce"]), grant.expires_at_ms)
_remember_native_path_for_redaction(str(resolved), grant.display_label)
return grant
def display_label_for_native_path(value: str | None) -> str | None:
if not value:
return value
with _REDACTION_LOCK:
return _NATIVE_PATH_LABELS.get(value, value)
def is_registered_native_path_label(path_value: str | None, label: str | None) -> bool:
if not path_value or not label:View on GitHub (pinned to 203007d190)
Solutions
- Have the user re-select a file whose extension matches what the endpoint accepts (e.g. .gguf).
- Sync the native dialog's file filter with the backend's allowed_suffixes for that endpoint so mismatches can't be picked in the first place.
- If a legitimate new format should be accepted, add its suffix to allowed_suffixes in the backend call site.
- Check for trailing whitespace or compound extensions on the filename (only the final .suffix segment is compared).
Example fix
# before
verify_native_path_lease(lease, operation="import_gguf", allowed_suffixes=(".gguf",))
# user selected weights.safetensors -> error
# after (frontend restricts the dialog)
const lease = await pickNativeFile({ filters: [{ name: "GGUF", extensions: ["gguf"] }] });
verify_native_path_lease(lease, operation="import_gguf", allowed_suffixes=(".gguf",)) Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
ALLOWED = {".gguf"}
def suffix_ok(path_str: str) -> bool:
return Path(path_str).suffix.lower() in ALLOWED Try / catch
try:
grant = verify_native_path_lease(lease, operation=OP, allowed_suffixes=(".gguf",))
except NativePathLeaseError as exc:
if "unsupported file type" in str(exc):
return error_response(400, "Only .gguf files are supported here.")
raise Prevention
- Set the native dialog's extension filter to the same set as allowed_suffixes.
- Keep filter lists in one shared constant used by frontend and backend.
- Validate the picked filename's suffix in the UI before enabling submit.
When it happens
Trigger: User picks a file with a different extension than the endpoint allows (e.g. .safetensors for a .gguf-only import); the file has no extension at all; double extensions where only the last suffix counts; or frontend filters on the dialog not matching the backend's allowed_suffixes list.
Common situations: Dialog file filters drifted out of sync with backend allowed_suffixes after a code change; users renaming files to force them through; case differences are handled (comparison is lowercased) but compound suffixes like .gguf.part or archive.gguf.tmp are not in the list.
Related errors
- Unsupported unstructured seed file type: {ext}
- unsupported file type: {ext}
- Not an image file. Allowed: {exts}
- Native path grant is required.
- Native path grant has the wrong path type.
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/69bc90a360d47e6e.
Report an issue: GitHub.