drive: fix two upload failures caused by Proton backend changes#1
Open
lmwashere wants to merge 1 commit intorclone:masterfrom
Open
drive: fix two upload failures caused by Proton backend changes#1lmwashere wants to merge 1 commit intorclone:masterfrom
lmwashere wants to merge 1 commit intorclone:masterfrom
Conversation
This commit fixes two bugs that prevent file uploads to Proton Drive:
--- Bug 1: handleRevisionConflict ignores ReplaceExistingDraft when
GetRevisions returns 2501 ---
When a previous upload attempt fails after the file draft is created but
before blocks are committed, a broken draft remains. On the next attempt
the draft is found (2500 "file already exists"), and GetRevisions is called
to decide what to do with it. However, broken drafts return 422/2501 from
the /revisions endpoint, causing handleRevisionConflict to return an error
immediately — even when ReplaceExistingDraft=true.
Fix: if GetRevisions fails AND ReplaceExistingDraft is set AND the link is
in draft state, treat it as a broken draft and delete the link so the caller
can retry from scratch.
--- Bug 2: block uploads missing required Verifier.Token ---
Proton's storage backend now requires a Verifier.Token per block in the
POST /drive/blocks request. Without it, the storage server rejects block
uploads with HTTP 422 / Code=200501 "Operation failed: Please retry".
The token is computed by fetching a VerificationCode for the revision via:
GET /drive/v2/volumes/{volumeID}/links/{linkID}/revisions/{revisionID}/verification
then XOR-ing it with the leading bytes of each block's ciphertext (algorithm
sourced from the official Proton Drive JS SDK in ProtonDriveApps/sdk).
Also bumps go-proton-api to v1.0.1-0.20260218123427-1a63a293e3a2 which
updates the default API host from mail.proton.me/api to drive-api.proton.me.
Note: the JS SDK performs an additional client-side decryption check before
computing the XOR token (to detect bit-flips / bad hardware). That step is
not implemented here; the server-side manifest signature still provides
end-to-end integrity verification. A future improvement could add it.
This fix was identified and generated with Claude Code (AI assistant) by a
non-programmer user (GitHub: lmwashere). It has not been independently
reviewed by a Go or cryptography expert. Expert review before merging is
strongly recommended.
Reproducer: rclone copy <file> proton: --verbose
Expected: upload succeeds
Actual: 422 POST fra-storage.proton.me/storage/blocks (Code=200501)
followed by 422 GET .../revisions (Code=2501) on retry
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This fixes two bugs that prevent file uploads to Proton Drive (broken as of ~Feb 2026):
Bug 1:
handleRevisionConflictignoresReplaceExistingDraftwhenGetRevisionsreturns 2501When a previous upload attempt fails after the file draft is created but before blocks are committed, a broken draft remains. On the next attempt the draft is found (2500 "file already exists"), and
GetRevisionsis called to decide what to do with it. However, broken drafts return 422/2501 from the/revisionsendpoint, causinghandleRevisionConflictto return an error immediately — even whenReplaceExistingDraft=true.Fix: if
GetRevisionsfails ANDReplaceExistingDraftis set AND the link is in draft state, treat it as a broken draft and delete the link so the caller can retry from scratch.Bug 2: block uploads missing required
Verifier.TokenProton's storage backend now requires a
Verifier.Tokenper block in thePOST /drive/blocksrequest. Without it, the storage server rejects block uploads with HTTP 422 / Code=200501.The token is computed by fetching a
VerificationCodefor the revision via:then XOR-ing it with the leading bytes of each block's ciphertext (algorithm sourced from the official Proton Drive JS SDK in ProtonDriveApps/sdk).
Also bumps
go-proton-apitov1.0.1-0.20260218123427-1a63a293e3a2which updates the default API host frommail.proton.me/apitodrive-api.proton.me(see rclone/go-proton-api#2).Reproducer:
rclone copy <file> proton: --verboseExpected: upload succeeds
Actual:
422 POST fra-storage.proton.me/storage/blocks (Code=200501)followed by422 GET .../revisions (Code=2501)on retryThis fix was identified and generated with Claude Code (AI assistant) by a non-programmer user (GitHub: lmwashere). It has not been independently reviewed by a Go or cryptography expert. Expert review before merging is strongly recommended.