{"record":{"id":"695a2c80da5da737","repo":"unslothai/unsloth","slug":"native-path-grant-kind-is-invalid","errorCode":null,"errorMessage":"Native path grant kind is invalid.","messagePattern":"Native path grant kind is invalid\\.","errorType":"validation","errorClass":"NativePathLeaseError","httpStatus":400,"severity":"error","filePath":"studio/backend/utils/native_path_leases.py","lineNumber":325,"sourceCode":"        \"operation\",\n        \"canonical_path\",\n        \"path_kind\",\n        \"path_type\",\n        \"source_kind\",\n        \"token_id_hash\",\n        \"issued_at_ms\",\n        \"expires_at_ms\",\n        \"nonce\",\n    )\n    missing = [key for key in required if key not in payload]\n    if missing:\n        raise NativePathLeaseError(\"Native path grant payload is missing required fields.\")\n    if _required_int(payload, \"version\") != 1:\n        raise NativePathLeaseError(\"Native path grant version is unsupported.\")\n    if payload[\"operation\"] != operation:\n        raise NativePathLeaseError(\"Native path grant operation is invalid.\")\n    if expected_kind and payload[\"path_kind\"] != expected_kind:\n        raise NativePathLeaseError(\"Native path grant kind is invalid.\")\n    now_ms = int(time.time() * 1000)\n    issued_at_ms = _required_int(payload, \"issued_at_ms\")\n    expires_at_ms = _required_int(payload, \"expires_at_ms\")\n    if issued_at_ms >= expires_at_ms:\n        raise NativePathLeaseError(\"Native path grant timestamps are inconsistent.\")\n    if expires_at_ms <= now_ms:\n        raise NativePathLeaseError(\"Native path grant has expired.\")\n    if issued_at_ms > now_ms + 30_000:\n        raise NativePathLeaseError(\"Native path grant issue time is invalid.\")\n    for key in (\"canonical_path\", \"nonce\", \"token_id_hash\", \"display_label\"):\n        raw = payload.get(key)\n        if raw is None:\n            continue\n        if \"\\x00\" in str(raw):\n            raise NativePathLeaseError(\"Native path grant contains invalid characters.\")\n\n\ndef _validate_current_stat(","sourceCodeStart":307,"sourceCodeEnd":343,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/native_path_leases.py#L307-L343","documentation":"expected_kind was passed to verify_native_path_lease() and the payload's path_kind doesn't match it. path_kind distinguishes what the grant is for (e.g. a picked single 'file' vs a 'document-folder' selection); endpoints restrict it so a folder-selection grant can't be used where only file-kind grants are valid, independent of path_type.","triggerScenarios":"Calling an endpoint expecting path_kind='file' with a grant from a document-folder picker (or vice versa); frontend mixing leases from a folder-scoped selection flow into a single-file API; test signers emitting an arbitrary path_kind value that the verifier's expected_kind rejects.","commonSituations":"UI flows that let users pick either a folder or a file but funnel both into the same submit handler; refactors renaming kind identifiers on one side; new sidecar features (e.g. mtp/dspark companion dirs) tightening expected_kind after grants were already issued under the old kind.","solutions":["Use the picker flow whose selection kind matches the endpoint's expected_kind and obtain a new grant from it.","Align path_kind literals between the Rust signer and each backend call site via shared constants.","Store leases keyed by (dialog, kind) in the frontend so a folder grant never reaches a file-only endpoint.","For test signers, emit exactly the path_kind the verifier expects."],"exampleFix":"# before\nlease = await pick_document_folder()\nverify_native_path_lease(lease, operation=\"load_weights\", expected_kind=\"file\")\n\n# after\nlease = await pick_native_file()\nverify_native_path_lease(lease, operation=\"load_weights\", expected_kind=\"file\")","handlingStrategy":"validation","validationCode":"# Frontend: bind each lease to the picker kind it came from\nif stored_lease.kind !== EXPECTED_KIND: throw new Error('wrong selection kind');","typeGuard":null,"tryCatchPattern":"try:\n    grant = verify_native_path_lease(lease, operation=OP, expected_kind=\"file\")\nexcept NativePathLeaseError as exc:\n    if \"kind is invalid\" in str(exc):\n        return error_response(400, \"This action needs a different kind of selection.\")\n    raise","preventionTips":["Namespace stored leases by (operation, kind).","Share path_kind literals as constants across Rust and Python.","Configure the picker for the exact kind the endpoint expects before opening the dialog."],"tags":["validation","file-picker","api-contract","kind-mismatch"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}