Skip to content

fix: use streaming multipart upload for files > 2 GiB in writeBinary#310

Open
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1779353702-fix-large-file-upload
Open

fix: use streaming multipart upload for files > 2 GiB in writeBinary#310
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1779353702-fix-large-file-upload

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot commented May 21, 2026

Summary

Fixes ERR_FS_FILE_TOO_LARGE error when calling writeBinary with a file path pointing to a file larger than 2 GiB.

Root cause: When writeBinary receives a string (file path), it calls fs.readFileSync(content) which tries to load the entire file into a Node.js Buffer. Node.js Buffers have a hard 2 GiB size limit, causing the error for files like the user's 17 GiB file.

Fix: Before calling readFileSync, check the file size with fs.statSync. If the file exceeds the multipart threshold (5 MB), use a new uploadFileWithMultipart method that:

  1. Opens the file with fs.openSync
  2. Reads 5 MB chunks sequentially using fs.readSync (bounded memory usage)
  3. Uploads each chunk as a multipart part (with parallel batching)
  4. Never loads the full file into memory

This approach handles files of any size without hitting the Buffer limit.

Review & Testing Checklist for Human

  • Test with a file > 2 GiB using writeBinary('/path/to/local/file') — should succeed without ERR_FS_FILE_TOO_LARGE
  • Test with a file < 5 MB using writeBinary('/path/to/small/file') — should still use the regular single-request upload path
  • Verify the uploaded file integrity by comparing checksums on the sandbox filesystem

Notes

  • This is a companion fix to sandbox PR #207 which makes CompleteUpload async on the server side to avoid CloudFront 504 timeouts during assembly
  • The existing uploadWithMultipart (Blob-based) path is unchanged — this adds a parallel uploadFileWithMultipart path specifically for local file paths that streams from disk

Link to Devin session: https://app.devin.ai/sessions/25c0534a826d4e088768cf2c15fa1d53
Requested by: @Joffref


Note

Adds a streaming multipart upload path for file-path inputs exceeding MULTIPART_THRESHOLD (5 MB), avoiding ERR_FS_FILE_TOO_LARGE when readFileSync hits the 2 GiB Buffer limit. Uses openSync/readSync with an absolute offset to read fixed-size chunks sequentially, uploading them in parallel batches before completing the multipart upload.

Written by Mendral for commit 19965a9.

When writeBinary receives a file path (string) for a file larger than
the multipart threshold, it now uses fd-based streaming (openSync/
readSync) to read and upload chunks without loading the entire file
into memory. This avoids the Node.js ERR_FS_FILE_TOO_LARGE error for
files exceeding the 2 GiB Buffer size limit.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Copy Markdown
Contributor

@mendral-app mendral-app Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

The implementation is correct and mirrors the existing blob-based uploadWithMultipart. The fd is properly guarded with a finally block, readSync with an absolute position argument is safe, Promise.all preserves insertion order so the sort is a harmless defensive step, and the abort-on-error path is wired correctly. The silent abort error swallow (line 532–534) matches common multipart conventions and is acceptable since the comment is explicit. No critical issues found.

Tag @mendral-app with feedback or questions. View session

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant