Skip to content

fix: verify resume identity and upload retries#93

Open
goanpeca wants to merge 27 commits into
mainfrom
fix/64-resume-candidate-identity
Open

fix: verify resume identity and upload retries#93
goanpeca wants to merge 27 commits into
mainfrom
fix/64-resume-candidate-identity

Conversation

@goanpeca

@goanpeca goanpeca commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary:

  • Verify resume candidate identity before reusing unfinished large files. Automatic and explicit resumes now check bucket, file name, content type, caller fileInfo, encryption, Object Lock retention, legal hold, legacy source and part-size metadata when present, and uploaded part lengths before reuse.
  • Throw ResumeFileIdMismatchError for incompatible explicit resumeFileId values, and keep SDK-managed resume metadata out of durable B2 fileInfo while still reading legacy resume metadata on existing unfinished uploads.
  • Make resume discovery deterministic, bounded, abortable, and tunable through resumeMaxListPages, resumeMaxPartCandidates, and resumeMaxPartPages, with structured rejection diagnostics that distinguish requested and candidate names. Explicit resumeFileId verification now keeps the requested namePrefix while jumping to startFileId so prefix-restricted keys can verify candidates.
  • Document the resume trust contract, SHA-1 residual risk for reused parts, orphaned unfinished-upload cleanup, discovery bounds, first-byte latency tradeoffs, event-only diagnostics, and SSE-C behavior. SSE-C is refused for automatic and explicit resume because B2 does not expose customer-key identity for unfinished uploads.
  • Model public B2 response encryption shapes without SSE-C secrets, including B2's null no-encryption wire shape, and align simulator responses plus unfinished-file response docs with those public shapes.
  • Add upload-layer fresh-URL retries for upload URLs and part URLs as a separate public behavior in this PR. Resolved retry settings are kept internal to client-created buckets and objects, RawClient request controls support the options-bag convention while preserving positional upload-URL overloads, concurrent part retries are documented as per-part with jittered backoff, and ambiguous single-file success-body retries are disabled by default unless callers opt in.
  • Preserve small-file behavior by stripping resume-only options from single-request uploads, remove dead resume helper exports, and expand coverage for resume matching, simulator fidelity, upload retry behavior, RawClient compatibility, request controls, and CI coverage gates.

Linked issue:

Tests run:

  • pnpm exec vitest run src/upload/resume.test.ts src/upload/upload-coverage.test.ts src/simulator/fidelity.test.ts src/client.test.ts src/raw.test.ts
  • pnpm exec vitest run src/raw.test.ts src/upload/resume.test.ts src/upload/upload-coverage.test.ts src/simulator/fidelity.test.ts
  • pnpm exec vitest run src/raw.test.ts
  • pnpm exec vitest run src/client.test.ts src/upload/resume.test.ts src/upload/upload-coverage.test.ts src/raw.test.ts
  • pnpm exec vitest run src/upload/upload-coverage.test.ts
  • pnpm run test:coverage
  • pnpm typecheck
  • pnpm lint
  • pnpm lint:docs
  • pnpm lint:spelling
  • pnpm test
  • pnpm run docs

Review status:

  • Review feedback has been addressed in follow-up commits.
  • Latest PR checks pass on commit b910aabc5aaf4fae5c69ed842644e867c6ce5cdd.

Follow-up notes:

  • No default SDK deadline was added for resume discovery or upload requests. Callers should pass an AbortSignal, such as AbortSignal.timeout(...), when they need a hard timeout.

Copilot AI review requested due to automatic review settings June 19, 2026 00:08
@goanpeca goanpeca added this to the v0.2.0 milestone Jun 19, 2026
@goanpeca goanpeca added bug Something isn't working priority: high High severity / do first area: upload Area: upload labels Jun 19, 2026
@goanpeca goanpeca self-assigned this Jun 19, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens multipart-upload resume behavior by making resume discovery verify an unfinished large file’s “identity” (source size/part size metadata + upload options) and selecting the newest compatible candidate, preventing same-name mismatches.

Changes:

  • Add SDK-managed resume identity metadata (source byte length + effective part size) and use it to conservatively filter/choose resume candidates.
  • Extend resume candidate selection to prefer the newest compatible unfinished large file and validate uploaded part byte lengths against the local plan.
  • Update simulator metadata + ordering to support the new resume identity contract, and add/extend regression + integration tests and documentation.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/upload/upload.slow.test.ts Updates slow resume test to include resume identity fileInfo and explicit contentType for compatible discovery.
src/upload/upload-coverage.test.ts Adds coverage test ensuring same-name conflicting unfinished uploads are skipped based on resume identity.
src/upload/resume.ts Implements resume identity keys, richer candidate criteria, newest-compatible selection, and part-length verification.
src/upload/resume.test.ts Adds unit tests for newest-candidate selection and mismatch filtering (options + part lengths).
src/upload/large.ts Writes resume identity metadata for SDK-started resumable uploads and passes full criteria into discovery.
src/types/upload.ts Expands unfinished-large-file metadata typing (timestamps, encryption, retention/legal hold, etc.).
src/simulator/index.ts Extends simulator unfinished-large-file metadata and changes listing order used by resume discovery.
src/object.ts Documents stricter resume discovery contract at the object upload API.
src/bucket.ts Documents stricter resume discovery contract at the bucket upload API.
README.md Documents the conservative resume identity contract and guidance for stable fileInfo across retries.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/simulator/index.ts Outdated
Copilot AI review requested due to automatic review settings June 19, 2026 00:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.

Comment thread src/upload/resume.ts
Comment thread src/upload/resume.ts
Comment thread src/upload/resume.ts
Comment thread src/types/upload.ts
Comment thread src/simulator/index.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.

Comment thread src/upload/resume.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Comment thread src/upload/resume.ts
Comment thread src/object.ts
Comment thread src/bucket.ts

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Comment thread src/upload/resume.ts Outdated
Comment thread src/upload/upload-coverage.test.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

@goanpeca goanpeca marked this pull request as ready for review June 19, 2026 01:31
Copilot AI review requested due to automatic review settings June 19, 2026 01:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Comment thread src/bucket.ts
Comment thread src/upload/resume.ts Outdated
Copilot AI review requested due to automatic review settings June 20, 2026 13:15
@goanpeca goanpeca force-pushed the fix/64-resume-candidate-identity branch from b910aab to 26c7055 Compare June 20, 2026 13:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated 1 comment.

Comment thread src/upload/retry.ts Outdated
Comment on lines +183 to +189
* file version. That response-body retry is disabled by default and requires
* `retryResponseBodyFailures: true`.
* file version; this is the idempotency tradeoff B2 documents for upload
* retries.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: upload Area: upload bug Something isn't working priority: high High severity / do first

Projects

None yet

Development

Successfully merging this pull request may close these issues.

upload: resume should verify unfinished large-file identity before reusing a candidate

2 participants