[BUG] Selecting Remote in a file conflict can upload the local file
Selecting the remote file in Zotero's file-conflict dialog can keep and upload the local file when both sides have the same modification timestamp. This can overwrite the remote file the user explicitly chose to keep.
2. While offline, replace its bytes differently on A and B. Give both files the same new filesystem modification time, later than the last synchronized time. Let Zotero's original file-change scanner detect both pending uploads.
3. Start syncing B and pause its upload-authorization request (
4. Synchronize A, allowing its changed file to become the remote version. Resume B's request so it encounters the conflicting remote hash and opens the file conflict dialog.
5. Select the remote/right-hand pane, click Finish, and allow synchronization to complete.
Remote file from A before resolution:
Local file on B before resolution:
File on B after selecting Remote:
File downloaded from zotero.org after resolution:
The automation clicked the right-hand pane’s actual groupbox, asserted its selected attribute was true, and clicked Finish. Observing the subsequent real upload request showed syncState=3 (SYNC_STATE_FORCE_UPLOAD) and A’s remote hash as If-Match. The upload completed, and B’s attachment ended as in_sync.
I downloaded the stored file before and after resolution and compared its bytes, so the result is an actual remote-file replacement, not just an incorrect MD5 in attachment metadata.
As a control, I repeated the same race with B’s file modification time one hour later than A’s. The displayed dates were 2026-10-30T01:36:32Z locally and 2026-10-30T00:36:32Z remotely. Selecting Remote then correctly downloaded A’s file and left the remote file unchanged. The failure was specific to the identical-date case in these tests.
Reproduction
1. Synchronize one imported file attachment between profiles A and B.2. While offline, replace its bytes differently on A and B. Give both files the same new filesystem modification time, later than the last synchronized time. Let Zotero's original file-change scanner detect both pending uploads.
3. Start syncing B and pause its upload-authorization request (
POST /users/<id>/items/{key}/file) before it reaches the server.4. Synchronize A, allowing its changed file to become the remote version. Resume B's request so it encounters the conflicting remote hash and opens the file conflict dialog.
5. Select the remote/right-hand pane, click Finish, and allow synchronization to complete.
Expected
B downloads A's remote file; the remote file remains A's version.Actual
B retains its own local bytes, uploads them over the remote file, and finishes with the attachment marked as synchronized.Observed evidence
The zotero.org run used a file modification time of 1793320544898 milliseconds on both sides. Both conflict objects had dateModified: "2026-10-30T00:35:44Z".Remote file from A before resolution:
18299ed1d339be92b91b9b316782b3c5Local file on B before resolution:
0901fdfa26a319db969fe3716531a27fFile on B after selecting Remote:
0901fdfa26a319db969fe3716531a27fFile downloaded from zotero.org after resolution:
0901fdfa26a319db969fe3716531a27fThe automation clicked the right-hand pane’s actual groupbox, asserted its selected attribute was true, and clicked Finish. Observing the subsequent real upload request showed syncState=3 (SYNC_STATE_FORCE_UPLOAD) and A’s remote hash as If-Match. The upload completed, and B’s attachment ended as in_sync.
I downloaded the stored file before and after resolution and compared its bytes, so the result is an actual remote-file replacement, not just an incorrect MD5 in attachment metadata.
As a control, I repeated the same race with B’s file modification time one hour later than A’s. The displayed dates were 2026-10-30T01:36:32Z locally and 2026-10-30T00:36:32Z remotely. Selecting Remote then correctly downloaded A’s file and left the remote file unchanged. The failure was specific to the identical-date case in these tests.
Upgrade Storage