Skip to content

Merge R2 upload & multipart docs#28186

Merged
elithrar merged 3 commits intoproductionfrom
opencode/issue28184-20260208155556
Feb 13, 2026
Merged

Merge R2 upload & multipart docs#28186
elithrar merged 3 commits intoproductionfrom
opencode/issue28184-20260208155556

Conversation

@ask-bonk
Copy link
Contributor

@ask-bonk ask-bonk bot commented Feb 8, 2026

All tasks are complete. Here's a summary of everything done:

Changes summary

Consolidated upload docs into a single page (/r2/objects/upload-objects/)

Restructured src/content/docs/r2/objects/upload-objects.mdx from a basic upload page into a comprehensive upload guide that merges content from the old multipart-objects.mdx page:

  • Added a comparison table at the top ("Choose an upload method") that helps users immediately understand when to use single upload vs. multipart upload, covering: best-for use cases, max object size, part sizes, resumability, parallelism
  • Workers API section with:
    • Single put() example with httpMetadata
    • Simple multipart example showing createMultipartUpload() / uploadPart() / complete() / abort() lifecycle
    • Full HTTP API Worker example for client-driven multipart uploads (cleaned up from the old workers-multipart-usage page)
    • Presigned URL example using aws4fetch (Workers-compatible)
  • S3 API section with TypeScript, JavaScript, and Python tabs for:
    • Single upload (PutObjectCommand / put_object)
    • Automatic multipart upload (@aws-sdk/lib-storage Upload / upload_file)
    • Manual multipart upload (low-level CreateMultipartUpload / UploadPart / CompleteMultipartUpload with proper abort-on-error)
    • Presigned URL generation (getSignedUrl / generate_presigned_url)
  • Multipart upload details section preserving the important reference material from the old page (part size limits, lifecycle policies, ETag calculation)
  • Related resources section with LinkCards

Deleted src/content/docs/r2/objects/multipart-objects.mdx

Updated public/__redirects

  • Added: /r2/objects/multipart-objects/ /r2/objects/upload-objects/ 301

Updated 3 files with internal links

  • src/content/release-notes/r2.yaml - Updated multipart ETags link
  • src/content/partials/r2/migrator-etag-caveat.mdx - Updated ETag calculation link
  • src/content/docs/r2/api/error-codes.mdx - Updated multipart upload link

Closes #28184

github run

Co-authored-by: elithrar <elithrar@users.noreply.github.com>
@ask-bonk ask-bonk bot mentioned this pull request Feb 8, 2026
@github-actions github-actions bot added product:r2 R2 object storage: https://developers.cloudflare.com/r2 size/l labels Feb 8, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 8, 2026

This PR requires additional review attention because it affects the following areas:

Redirects

This PR changes current filenames or deletes current files. Make sure you have redirects set up to cover the following paths:

  • /r2/objects/multipart-objects/

Partials

This PR updates partial files, which are pieces of content used across multiple files in our Render component.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 8, 2026

This pull request requires reviews from CODEOWNERS as it changes files that match the following patterns:

Pattern Owners
/public/__redirects @cloudflare/content-engineering, @cloudflare/pcx-technical-writing
/src/content/docs/r2/ @oxyjun, @elithrar, @jonesphillip, @aninibread, @harshil1712, @cloudflare/workers-docs, @cloudflare/pcx-technical-writing
/src/content/partials/r2/ @elithrar, @rita3ko, @irvinebroque, @vy-ton, @cloudflare/pcx-technical-writing
/src/content/release-notes/r2.yaml @oxyjun, @elithrar, @aninibread, @cloudflare/workers-docs, @cloudflare/pcx-technical-writing

@elithrar
Copy link
Collaborator

elithrar commented Feb 8, 2026

Cc @aninibread @jonesphillip

- Add error handling (try/catch) to Workers single upload example
- Handle null return from put() (precondition failure)
- Define placeholder variables in Workers multipart example (was using undefined vars)
- Wrap Workers presigned URL in a proper fetch handler with env secrets
- Remove unused ctx parameter from all Workers examples
- Wrap abort calls in try/catch in manual multipart examples (TS/JS/Python)
  to avoid masking the original error
- Fix progress.total potentially undefined in auto multipart upload
- Add console.log/print output to S3 examples for copy-paste clarity
- Remove unnecessary Buffer type annotation in TS single upload
@ask-bonk
Copy link
Contributor Author

ask-bonk bot commented Feb 8, 2026

Here's a summary of my rigorous review and the fixes I applied:


Code review summary

I reviewed all 8 code examples (12 language variants total) against the criteria: concise, safe to copy+paste, error handling, and best practices.

Issues found and fixed

# Example Issue Severity
1 Workers single upload No error handling; object?.key silently returns null properties with 200 status High
2 Workers multipart firstChunk and secondChunk are undefined variables -- code throws ReferenceError if copy+pasted High
3 Workers presigned URL Hardcoded credentials in top-level scope (not in env); not wrapped in a Worker handler unlike every other Workers example; no output High
4 S3 manual multipart (all 3 langs) abort() in catch block can itself throw, masking the original error Medium
5 S3 auto multipart (TS/JS) progress.total is undefined for streams -- log prints "undefined" Medium
6 All Workers examples Unused ctx: ExecutionContext parameter Low
7 TS single upload Unnecessary Buffer type annotation Low
8 S3 examples No visible output -- user can't tell if script succeeded Low

What was already good

  • Workers HTTP API multipart example (lines 116-190): Input validation, try/catch on each operation, proper use of resumeMultipartUpload(). This was the strongest example.
  • S3 manual multipart structure: Correct try/catch + abort pattern, proper part tracking, correct createReadStream options with inclusive end.
  • API usage is correct: httpEtag used for HTTP headers, etag used for JSON responses, R2UploadedPart[] type correctly used.
  • Python examples: Clean, idiomatic, correct use of context managers.

Remaining notes (no fix needed)

  • The S3 presigned URL examples are script-style (no function wrapper) which is intentionally different from Workers examples -- this is correct since they're meant to run as server-side Node.js/Python scripts.
  • The <ACCOUNT_ID>, <ACCESS_KEY_ID>, <SECRET_ACCESS_KEY> placeholder pattern is consistent across all examples and follows Cloudflare docs conventions.

github run

Co-authored-by: elithrar <elithrar@users.noreply.github.com>
@ask-bonk
Copy link
Contributor Author

ask-bonk bot commented Feb 8, 2026

Here's a summary of the changes:

Converted all 4 Workers API code blocks to use <TypeScriptExample>:

  1. Single upload (line 50) -- put() example
  2. Simple multipart upload (line 84) -- createMultipartUpload() example
  3. HTTP API multipart (line 123) -- full client-driven multipart Worker
  4. Presigned URLs (Workers) (line 207) -- aws4fetch presigned URL example

Each bare ```ts block is now wrapped in <TypeScriptExample> ... </TypeScriptExample>, which will auto-generate a JavaScript tab by stripping TypeScript annotations via ts-blank-space and formatting with Prettier. The TypeScriptExample import was added to the frontmatter imports.

The S3 API section examples were intentionally left as manual <Tabs>/<TabItem> because they include Python variants alongside TypeScript/JavaScript, which TypeScriptExample doesn't support.

Note: A full build couldn't run in this CI environment due to a Node.js version mismatch (requires Node 22.x, has 20.x), but the changes follow the exact same pattern used across 100+ other MDX files in the codebase.

github run

@elithrar

This comment was marked as outdated.

1 similar comment
@elithrar
Copy link
Collaborator

/bonk run a final review and ensure all code examples meet our bar.

@ask-bonk
Copy link
Contributor Author

ask-bonk bot commented Feb 12, 2026

Final review: All code examples meet the bar

I reviewed all 12 code examples (8 blocks, 12 language variants) across the file plus the surrounding infrastructure (redirects, links, components). Here's the summary:

Code examples -- all pass

# Example Lines Verdict
1 Workers single put() 52-76 Correct. Null check for precondition failure, try/catch, streams request.body directly.
2 Workers simple multipart 86-117 Correct. Placeholder data with comments, abort-on-failure, httpEtag for response headers (recommended by Cloudflare).
3 Workers HTTP API multipart 125-197 Correct. Input validation, resumeMultipartUpload() used synchronously (no await -- correct since it's not async), proper R2UploadedPart[] typing, per-action error handling.
4 Workers presigned URL (aws4fetch) 209-239 Correct. Credentials from env, signQuery: true for query-string signing, X-Amz-Expires as query param.
5 S3 single upload (TS/JS/Python) 254-333 Correct. readFile/open("rb"), PutObjectCommand/put_object, ETag output.
6 S3 automatic multipart (TS/JS/Python) 347-437 Correct. @aws-sdk/lib-storage Upload with leavePartsOnError: false, progress.loaded ?? 0 (handles undefined), upload_file for Python.
7 S3 manual multipart (TS/JS/Python) 447-657 Correct. createReadStream with inclusive end - 1, ContentLength specified, abort in nested try/catch (best-effort cleanup), re-throws original error.
8 S3 presigned URL (TS/JS/Python) 667-752 Correct. getSignedUrl/generate_presigned_url, expiresIn: 3600.

Infrastructure -- all pass

  • TypeScriptExample components: All 4 Workers examples correctly use <TypeScriptExample> wrapping ```ts fenced blocks, matching the pattern used across 500+ other files in the codebase.
  • Redirect: /r2/objects/multipart-objects/ /r2/objects/upload-objects/ 301 is in public/__redirects at line 1588.
  • Deleted file: multipart-objects.mdx no longer exists.
  • Internal links: Zero remaining references to /r2/objects/multipart-objects/ anywhere in src/. The release notes and partial files both updated to point to /r2/objects/upload-objects/#etags.
  • S3 tabs: Correctly use manual <Tabs>/<TabItem> (not TypeScriptExample) since they include Python, which TypeScriptExample doesn't support.

No changes needed

All examples are correct, safe to copy-paste, handle errors properly, and follow best practices for their respective languages/SDKs. The previous review rounds caught and fixed the real issues (undefined variables, hardcoded credentials, missing error handling). This PR is in good shape.

github run

@elithrar elithrar enabled auto-merge (squash) February 12, 2026 15:21
@elithrar elithrar merged commit 6d69872 into production Feb 13, 2026
9 checks passed
@elithrar elithrar deleted the opencode/issue28184-20260208155556 branch February 13, 2026 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

product:r2 R2 object storage: https://developers.cloudflare.com/r2 size/l

Projects

None yet

Development

Successfully merging this pull request may close these issues.

r2 upload docs improvements

9 participants