{"record":{"id":"ac775900eb072f61","repo":"unslothai/unsloth","slug":"native-path-grant-payload-is-invalid","errorCode":null,"errorMessage":"Native path grant payload is invalid.","messagePattern":"Native path grant payload is invalid\\.","errorType":"validation","errorClass":"NativePathLeaseError","httpStatus":400,"severity":"error","filePath":"studio/backend/utils/native_path_leases.py","lineNumber":296,"sourceCode":"\ndef _split_lease(lease: str) -> tuple[str, str]:\n    if not isinstance(lease, str):\n        raise NativePathLeaseError(\"Native path grant has an invalid format.\")\n    try:\n        lease.encode(\"ascii\")\n    except UnicodeEncodeError as exc:\n        raise NativePathLeaseError(\"Native path grant has an invalid format.\") from exc\n    parts = lease.split(\".\")\n    if len(parts) != 2 or not parts[0] or not parts[1]:\n        raise NativePathLeaseError(\"Native path grant has an invalid format.\")\n    return parts[0], parts[1]\n\n\ndef _decode_payload(payload_b64: str) -> dict[str, Any]:\n    try:\n        payload = json.loads(_b64decode(payload_b64).decode(\"utf-8\"))\n    except Exception as exc:\n        raise NativePathLeaseError(\"Native path grant payload is invalid.\") from exc\n    if not isinstance(payload, dict):\n        raise NativePathLeaseError(\"Native path grant payload is invalid.\")\n    return payload\n\n\ndef _validate_payload(\n    payload: dict[str, Any], *, operation: str, expected_kind: str | None\n) -> None:\n    required = (\n        \"version\",\n        \"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\",","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/native_path_leases.py#L278-L314","documentation":"The payload half of the lease could not be base64url-decoded and parsed as UTF-8 JSON — _b64decode or json.loads raised inside _decode_payload. Signature verification already passed (it covers the raw segment bytes), so this indicates a signer bug or an environment where a valid signature exists over garbage payload bytes.","triggerScenarios":"A signing implementation (custom dev harness) that produces a correct HMAC over a payload segment that isn't valid base64url JSON; padding characters misplaced inside the segment; or a payload segment built with standard base64 ('+','/') instead of base64url ('-','_').","commonSituations":"Writing your own Rust/Python test signer rather than using the desktop shell's; version drift between an old signer that used standard base64 and the current urlsafe decoder; or hand-crafted tokens in security tests.","solutions":["Use the managed Tauri shell to issue grants, or replicate its exact format: base64url(json_utf8) + '.' + base64url(hmac_sha256(payload_b64_ascii)).","Check your test signer uses urlsafe encoding without embedded '+', '/', or misplaced '=' padding.","Confirm both halves are encoded, not just the signature — the payload segment must also be base64url."],"exampleFix":"# before (test signer)\npayload_b64 = base64.b64encode(json.dumps(p).encode()).decode()      # standard base64\n\n# after\npayload_b64 = base64.urlsafe_b64encode(json.dumps(p).encode()).decode().rstrip('=')\nlease = payload_b64 + '.' + base64.urlsafe_b64encode(sig).decode().rstrip('=')","handlingStrategy":"try-catch","validationCode":"import base64, json\n\ndef payload_decodes(lease: str) -> bool:\n    try:\n        seg = lease.split(\".\")[0]\n        json.loads(base64.urlsafe_b64decode(seg + \"=\" * (-len(seg) % 4)).decode(\"utf-8\"))\n        return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    grant = verify_native_path_lease(lease, operation=OP)\nexcept NativePathLeaseError as exc:\n    if \"payload is invalid\" in str(exc):\n        return error_response(400, \"File grant payload is malformed.\")\n    raise","preventionTips":["Mirror the Rust signer's urlsafe base64 exactly in test harnesses.","Property-test your signer: every issued grant must decode to a JSON object.","Keep a known-good golden grant fixture to validate transport end-to-end."],"tags":["base64","json","token-format","signing"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}