bytedance/deer-flow · error · HTTPException
Failed to upload {file.filename}: {str(e)}
Error message
Failed to upload {file.filename}: {str(e)} What it means
HTTP 500 raised when an unexpected (non-HTTP, non-UnsafeUploadPath) exception escapes while processing one file in a multi-file upload. The gateway cleans up all files already written in this request (written_paths) before failing, so the upload is atomic. The detail includes the original exception text for the offending file.
Source
Thrown at backend/app/gateway/routers/uploads.py:419
else:
# Conversion failed and wrote nothing, so release the claim;
# holding it would rename a later same-stem upload against
# a name nothing occupies.
seen_filenames.discard(unique_md_name)
uploaded_files.append(file_info)
except HTTPException as e:
await run_file_io(_cleanup_uploaded_paths, written_paths)
raise e
except UnsafeUploadPathError as e:
logger.warning("Skipping upload with unsafe destination %s: %s", file.filename, e)
skipped_files.append(safe_filename)
continue
except Exception as e:
logger.error(f"Failed to upload {file.filename}: {e}")
await run_file_io(_cleanup_uploaded_paths, written_paths)
raise HTTPException(status_code=500, detail=f"Failed to upload {file.filename}: {str(e)}")
# Uploaded files are created with 0o600 permissions (owner read/write only).
# In Docker sandbox deployments the gateway writes as root but the sandbox
# process runs as a non-root user (typically UID 1000). Without group/other
# read bits the sandbox cannot access the files — whether the uploads
# directory is bind-mounted into the container or synced via
# sandbox.update_file. Always add group/other read bits so every sandbox
# configuration can read the uploaded content.
await run_file_io(_make_uploaded_paths_sandbox_readable, written_paths)
if sync_to_sandbox:
for file_path, virtual_path in sandbox_sync_targets:
await run_file_io(_sync_upload_to_sandbox, sandbox, file_path, virtual_path)
message = f"Successfully uploaded {len(uploaded_files)} file(s)"
if skipped_files:
message += f"; skipped {len(skipped_files)} unsafe file(s)"
View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Read the {str(e)} portion of the detail and the gateway log line 'Failed to upload <filename>' — it names the actual cause (OSError, ENOSPC, EACCES, converter error).
- Fix the underlying filesystem issue: free disk space, correct ownership/permissions on the thread uploads directory.
- If the error comes from auto-convert, disable uploads.auto_convert_documents in config or install the required converter, then retry.
- Retry the upload after fixing — cleanup already removed partial writes, so the thread is in a clean state.
Defensive patterns
Strategy: try-catch
Try / catch
catch 500 from the upload endpoint; parse detail for the per-file cause; the gateway already cleaned partial writes, so after fixing the cause a plain retry is safe.
Prevention
- Alert on gateway disk usage so ENOSPC never reaches uploads.
- Verify ownership/permissions of the uploads volume in deployment checks.
- Test the document-conversion toolchain when enabling auto-convert.
When it happens
Trigger: Any per-file I/O or processing failure during the upload loop: disk full, permission denied writing to the uploads dir, failure in the auto-convert-documents step, or sandbox file-sync errors raised inside the loop.
Common situations: Gateway container out of disk or inode-exhausted; uploads volume mounted read-only or owned by the wrong user; document conversion subprocess missing its binary; a filesystem watchdog/AV scanner locking files mid-write.
Related errors
- Failed to delete {filename}: {str(e)}
- Failed to list agents: {str(e)}
- Failed to get agent: {str(e)}
- Failed to update agent: {str(e)}
- Failed to read user profile: {str(e)}
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/55f282bc2d88d07b.
Report an issue: GitHub.