unslothai/unsloth · error · HTTPException
failed to delete uploaded files
Error message
failed to delete uploaded files
What it means
HTTP 500 raised by DELETE /seed/unstructured-block/{block_id} when shutil.rmtree raises OSError, or when the rmtree call returned but block_dir still exists (partial delete). It is logged via log_and_http_error with event data_recipe.seed.unstructured_block_delete_failed.
Source
Thrown at studio/backend/routes/data_recipe/seed.py:616
block_dir = (UNSTRUCTURED_UPLOAD_ROOT / block_id).resolve()
if not block_dir.is_relative_to(UNSTRUCTURED_UPLOAD_ROOT.resolve()):
raise HTTPException(400, "Invalid block_id: outside upload root")
if not block_dir.exists():
return {"status": "ok", "deleted": False}
try:
shutil.rmtree(block_dir)
except OSError as exc:
raise log_and_http_error(
exc,
500,
"failed to delete uploaded files",
event = "data_recipe.seed.unstructured_block_delete_failed",
log = logger,
) from exc
if block_dir.exists():
raise HTTPException(500, "failed to delete uploaded files")
return {"status": "ok", "deleted": True}
@router.post("/seed/inspect-upload", response_model = SeedInspectResponse)
def inspect_seed_upload(payload: SeedInspectUploadRequest) -> SeedInspectResponse:
if payload.file_ids is not None:
if len(payload.file_ids) == 0:
raise HTTPException(400, "file_ids must not be empty")
_validate_safe_id(payload.block_id, "block_id")
for fid in payload.file_ids:
_validate_safe_id(fid, "file_id")
preview_rows = _read_preview_rows_from_multi_files(
block_id = payload.block_id,
file_ids = payload.file_ids,
file_names = payload.file_names,
preview_size = payload.preview_size,
chunk_size = payload.unstructured_chunk_size,
chunk_overlap = payload.unstructured_chunk_overlap,View on GitHub (pinned to 203007d190)
Solutions
- Retry the delete after the concurrent upload/preview finishes — the most common cause is a race with an in-flight write.
- Check directory permissions/ownership of the uploads root for the backend process user.
- If it persists, list surviving files in the block dir to identify which file cannot be removed and why (lsof/permissions).
Example fix
# before
await api.deleteBlock(blockId) # one-shot, throws on race
# after
for attempt in range(3):
try:
await api.deleteBlock(blockId); break
except HttpError as e:
if e.status != 500 or attempt == 2: raise
await asyncio.sleep(1) # let concurrent upload finish Defensive patterns
Strategy: retry
Try / catch
Catch the 500 'failed to delete uploaded files', wait briefly (concurrent write race is the usual cause), and retry the block delete up to 2–3 times with backoff; escalate to manual filesystem inspection if it persists.
Prevention
- Block new uploads to a block before deleting it (disable the UI).
- Check permissions on the uploads root for the backend user in container images.
- Avoid running cleanup jobs that rmtree the same directories concurrently.
When it happens
Trigger: Block delete when files are locked/open (Windows), permission bits deny removal, another process concurrently recreates files in the directory, or an NFS/container volume races the delete.
Common situations: Concurrent uploads to the same block during delete; read-only mounts; files held open by an extraction subprocess; container volume with slow eventual consistency.
Related errors
- Models folder path is not a directory: {path}
- Linked folder changed after it was selected
- Failed to read the local dataset cache.
- Failed to delete dataset from {len(failures)} cache location
- Failed to create models folder: {path}: {e}
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/27c71be6278e6411.
Report an issue: GitHub.