{"record":{"id":"bdb34da205c6c4b2","repo":"unslothai/unsloth","slug":"failed-to-delete-dataset-from-len-failures-cach","errorCode":null,"errorMessage":"Failed to delete dataset from {len(failures)} cache location(s). Some files may remain.","messagePattern":"Failed to delete dataset from (.+?) cache location\\(s\\)\\. Some files may remain\\.","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"studio/backend/hub/services/datasets/cache_inventory.py","lineNumber":639,"sourceCode":"        }\n\n    processed_deleted, processed_failures = _delete_processed_dataset_cache(\n        repo_id, only_roots = processed_roots\n    )\n    failures.extend(processed_failures)\n    delete_app_cache = not cache_path or app_entry is not None or target_root is not None\n    app_hub_cache = app_entry.hub_cache if app_entry is not None else target_root\n    app_deleted, app_failures = (\n        _delete_app_processed_dataset_cache(\n            repo_id,\n            hub_cache = app_hub_cache,\n        )\n        if delete_app_cache\n        else (False, [])\n    )\n    failures.extend(app_failures)\n    if failures:\n        raise HTTPException(\n            status_code = 500,\n            detail = (\n                f\"Failed to delete dataset from {len(failures)} cache \"\n                \"location(s). Some files may remain.\"\n            ),\n        )\n\n    # ``scan_cache_dir()`` skips blob-only/corrupt repos the revision delete can't touch, yet the\n    # fallback scanner shows them, so purge the whole dir. Hub cache targets only.\n    cache_purged = partial_purged = state_purged = False\n    if target_root is not None:\n        cache_purged = purge_repo_cache_dirs(\"dataset\", repo_id, root = target_root)\n        partial_purged = purge_partial_repo(\"dataset\", repo_id, root = target_root)\n        state_purged = (\n            download_manifest.purge_all_state_for_repo(\"dataset\", repo_id, hub_cache = target_root)\n            > 0\n        )\n    if not (","sourceCodeStart":621,"sourceCodeEnd":657,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/hub/services/datasets/cache_inventory.py#L621-L657","documentation":"Raised as HTTP 500 after a dataset cache-deletion pass collected one or more per-location failures. The endpoint walks multiple cache locations (HF hub cache revision deletes, processed-dataset roots, app-processed cache) and accumulates failures; if any location failed, it reports how many failed and warns that files may remain on disk. It is a partial-failure error: some locations may already have been deleted.","triggerScenarios":"Calling the delete-dataset-cache endpoint for a repo_id whose cache directories live under a root the process cannot write/delete (permission denied), blobs locked by another process on Windows, an NFS/SID-mapped mount, or a path removed mid-walk between scan and delete.","commonSituations":"Cache dirs created by root or a different user during earlier runs; read-only mounts; concurrent downloads writing into the same snapshot dir while deletion runs; antivirus/IDE holding file handles open.","solutions":["Check the server logs for the per-location failure messages appended to `failures` before the raise; they name the exact paths and OS errors.","Fix filesystem permissions on the reported cache roots (chown/chmod) so the backend process owns the snapshot/refs/blobs dirs.","Stop concurrent downloads or Studio jobs touching the same repo_id, then retry the delete request.","If the location is externally managed (read-only mount), delete it manually with rm -rf on the reported path and re-run the endpoint to confirm a clean 200."],"exampleFix":"# before: cache dirs owned by root after a docker run as root\n# ls -lan ~/.cache/huggingface/hub/datasets__foo  -> uid 0\nsudo chown -R $(id -u):$(id -g) ~/.cache/huggingface/hub\n# after: retry DELETE /datasets/cache {\"repo_id\": \"foo\"} -> 200 {\"status\": \"deleted\"}","handlingStrategy":"retry","validationCode":"# Before deleting, confirm writability of the cache roots you expect to touch\nimport os\nfrom pathlib import Path\n\ndef cache_roots_writable(roots: list[Path]) -> list[str]:\n    problems = []\n    for r in roots:\n        if r.exists() and not os.access(r, os.W_OK | os.X_OK):\n            problems.append(str(r))\n    return problems","typeGuard":null,"tryCatchPattern":"try:\n    delete_dataset_cache(client, repo_id)\nexcept HTTPStatusError as e:\n    if e.response.status_code == 500 and \"cache location\" in e.response.text:\n        # partial failure: read server logs for per-path failures, fix perms, retry once\n        fix_permissions_from_logs(); retry_once()\n    else:\n        raise","preventionTips":["Run the backend as the same user that created the HF cache directories.","Avoid issuing cache deletes while downloads for the same repo_id are active.","Monitor the returned failure count; a growing count usually means a mounting/permission regression."],"tags":["cache","filesystem","permissions","partial-failure","http-500"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}