{"record":{"id":"080ec44f9e876bbe","repo":"unslothai/unsloth","slug":"dropped-dataset-could-not-be-read","errorCode":null,"errorMessage":"Dropped dataset could not be read.","messagePattern":"Dropped dataset could not be read\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"studio/backend/hub/services/datasets/local.py","lineNumber":339,"sourceCode":"    except NativePathLeaseError as exc:\n        raise HTTPException(status_code = 400, detail = str(exc)) from exc\n\n    filename, stored_path, max_bytes, max_label = _upload_destination(grant.canonical_path.name)\n    if grant.size_bytes is not None and grant.size_bytes > max_bytes:\n        raise _upload_too_large(max_label)\n\n    written = 0\n    upload_complete = False\n    try:\n        with open(grant.canonical_path, \"rb\") as source, open(stored_path, \"wb\") as target:\n            while chunk := source.read(LOCAL_UPLOAD_CHUNK_BYTES):\n                written += len(chunk)\n                if written > max_bytes:\n                    raise _upload_too_large(max_label)\n                target.write(chunk)\n        upload_complete = True\n    except OSError as exc:\n        raise HTTPException(\n            status_code = 400,\n            detail = \"Dropped dataset could not be read.\",\n        ) from exc\n    finally:\n        if not upload_complete:\n            with suppress(OSError):\n                stored_path.unlink(missing_ok = True)\n\n    if written == 0:\n        stored_path.unlink(missing_ok = True)\n        raise HTTPException(status_code = 400, detail = \"Dropped dataset is empty\")\n\n    return UploadDatasetResponse(filename = filename, stored_path = str(stored_path))\n\n\nasync def upload_dataset_response(\n    file: UploadFile | None, native_path_lease: str | None = None\n) -> UploadDatasetResponse:","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/hub/services/datasets/local.py#L321-L357","documentation":"HTTP 400 from native upload when copying the leased source file to storage raised an OSError — typically the source disappeared, became unreadable (permissions), or the destination write failed (disk full). The partial destination file is cleaned up in the finally block, so no orphan stored_path remains. The original OSError is chained (from exc) but the client only gets the generic message; the server traceback has the specifics.","triggerScenarios":"The user moved/deleted/renamed the picked file between lease grant and import; source file locked by another process; destination disk full mid-copy; unreadable source due to OS permissions.","commonSituations":"Picking a file from a transient location (Downloads being cleaned, external drive unplugged, network share dropped); disk-full Studio volumes.","solutions":["Confirm the source file still exists at the same path and is readable, then re-import.","Check destination disk space on the backend host (df -h on the upload dir).","On Windows, close programs holding the file (Excel, sync clients) and retry.","If it recurs, pull the chained OSError from server logs to identify read vs write failure."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"def source_readable(path: Path) -> bool:\n    try:\n        with path.open(\"rb\") as f:\n            return f.read(1) == b\"\" or True  # open+read proves readability\n    except OSError:\n        return False\n\ndef disk_has_space(dest_dir: Path, needed: int) -> bool:\n    return shutil.disk_usage(dest_dir).free > needed * 1.1","typeGuard":null,"tryCatchPattern":"try:\n    upload_dataset(client, native_path_lease=lease)\nexcept HTTPStatusError as e:\n    if e.response.status_code == 400 and \"could not be read\" in e.response.text:\n        reselect_file_and_retry()  # source vanished/locked; destination was auto-cleaned\n    else:\n        raise","preventionTips":["Import immediately after picking; long gaps between pick and import are the top cause.","Avoid importing from removable/network mounts that can disconnect.","Monitor free space on the backend's upload volume."],"tags":["upload","native-import","filesystem","http-400"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}