Skip to content

fix: use fileId for upload queue identity instead of file.name#3785

Open
Crash-- wants to merge 6 commits intomasterfrom
fix/upload-queue-fileId-identity
Open

fix: use fileId for upload queue identity instead of file.name#3785
Crash-- wants to merge 6 commits intomasterfrom
fix/upload-queue-fileId-identity

Conversation

@Crash--
Copy link
Copy Markdown
Contributor

@Crash-- Crash-- commented Apr 6, 2026

Summary

  • Fix a bug where the upload queue reducer matches items by file.name, causing two files with the same name (e.g. summer/photo.jpg and winter/photo.jpg) to collide — an action targeting one incorrectly updates both
  • Introduce a fileId field on queue items (defaults to file.name for backward compatibility) used as the identity key in the reducer
  • This is a prerequisite for the folder upload flattening feature, where files from different sub-folders will appear individually in the queue

Test plan

  • 3 new unit tests demonstrate the collision bug and pass after the fix
  • All 33 existing tests pass
  • Manual test: upload two files with the same name to different folders and verify independent progress/status tracking

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Upload queue now assigns a stable per-file identifier so uploads, progress updates, overwrites, removals and error handling reliably target the correct file—even when files share the same name. Conflict-overwrite and quota/error flows now report progress and completion consistently.
  • Tests

    • Expanded test coverage validating per-file identifier behavior across progress, success, error, overwrite and duplicate-name scenarios, plus backward compatibility.

Crash-- and others added 2 commits April 6, 2026 13:33
The reducer matches queue items by file.name, so two files with the
same name (e.g. from different sub-folders) collide: an action targeting
one updates both. These 3 tests demonstrate the bug.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The reducer matched queue items by file.name, causing two files with
the same name (e.g. from different sub-folders) to collide. Switching
to a dedicated fileId field (defaults to file.name for backward compat)
fixes this and prepares for folder upload flattening.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 6, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Queue items now include a normalized fileId (from item.fileId or fallbacks like item.file?.name / item.entry?.name). Reducer handling for UPLOAD_PROGRESS, UPLOAD_FILE, RECEIVE_UPLOAD_SUCCESS, and RECEIVE_UPLOAD_ERROR matches items by fileId (with fallback to action.file?.name). uploadProgress and removeFileToUploadQueue signatures accept fileId. processNextFile and conflict overwrite flow propagate fileId through dispatched actions and progress updates. Error mapping moved to getUploadErrorStatus. Tests were updated to assert fileId propagation and compatibility when RECEIVE_UPLOAD_SUCCESS omits fileId.

Suggested reviewers

  • lethemanh
  • JF-Cozy
  • doubleface
  • zatteo
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: introducing fileId as the identity key for upload queue items instead of file.name to fix a collision bug.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/upload-queue-fileId-identity

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

codescene-delta-analysis[bot]

This comment was marked as outdated.

}

const { file, entry, isDirectory } = item
const { file, fileId, entry, isDirectory } = item
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think we should merge this fix as is.

i'm working on improving things in an other PR.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/modules/upload/index.js (2)

485-487: Good backward-compatible fallback in removeFileToUploadQueue.

The fileId ?? file.name fallback ensures callers that don't yet provide fileId will continue to work.

Minor: Prettier flagged the formatting. Consider expanding to multiple lines.

Formatting fix
 export const removeFileToUploadQueue = (file, fileId) => async dispatch => {
-  dispatch({ type: RECEIVE_UPLOAD_SUCCESS, fileId: fileId ?? file.name, file, isUpdate: true })
+  dispatch({
+    type: RECEIVE_UPLOAD_SUCCESS,
+    fileId: fileId ?? file.name,
+    file,
+    isUpdate: true
+  })
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/upload/index.js` around lines 485 - 487, The function
removeFileToUploadQueue currently uses a compact one-line arrow that Prettier
flagged; refactor it into a multi-line arrow function to improve formatting and
readability: locate export const removeFileToUploadQueue and expand the async
dispatch => block so the dispatch({ type: RECEIVE_UPLOAD_SUCCESS, fileId: fileId
?? file.name, file, isUpdate: true }) call is on its own line(s) with proper
indentation and trailing semicolon, preserving the fallback behavior (fileId ??
file.name) and the action type RECEIVE_UPLOAD_SUCCESS.

225-225: Minor: Format the inline dispatch object.

ESLint/Prettier flagged this line for formatting.

Suggested fix
-        dispatch({ type: RECEIVE_UPLOAD_SUCCESS, fileId, file, uploadedItem: newDir })
+        dispatch({
+          type: RECEIVE_UPLOAD_SUCCESS,
+          fileId,
+          file,
+          uploadedItem: newDir
+        })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/upload/index.js` at line 225, The inline dispatch call dispatch({
type: RECEIVE_UPLOAD_SUCCESS, fileId, file, uploadedItem: newDir }) is flagged
by ESLint/Prettier for formatting; reformat the object literal passed to
dispatch (the call in which RECEIVE_UPLOAD_SUCCESS, fileId, file, and
uploadedItem: newDir are used) into a properly indented multi-line object with
each property on its own line and appropriate trailing commas to satisfy the
project's linting rules.
src/modules/upload/index.spec.js (1)

679-679: Minor: Format the inline object across multiple lines.

ESLint/Prettier flagged this line for formatting.

Suggested fix
-      const result3 = queue(result2, { type: 'RECEIVE_UPLOAD_ERROR', fileId, file })
+      const result3 = queue(result2, {
+        type: 'RECEIVE_UPLOAD_ERROR',
+        fileId,
+        file
+      })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modules/upload/index.spec.js` at line 679, The inline object passed to
queue in the test is currently on one line (const result3 = queue(result2, {
type: 'RECEIVE_UPLOAD_ERROR', fileId, file })) and needs to be formatted across
multiple lines to satisfy ESLint/Prettier; update the call to queue(result2, {
... }) so the object properties (type, fileId, file) are each on their own lines
(and keep result3 and result2 identifiers unchanged) ensuring commas and
indentation follow the project's formatting rules.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/modules/upload/index.js`:
- Around line 56-61: itemInitialState currently assumes item.file is non-null
and accesses item.file.name which throws for directory entries from
extractFilesEntries (where item.getAsFile() returns null); update
itemInitialState to derive fileId safely using optional chaining and a fallback
to the entry name (e.g. use item.file?.name ?? item.name or similar) so
directories get a valid fileId without accessing .name on null; ensure this
change is applied to the itemInitialState function so the reducer call that
initializes queue entries no longer causes a TypeError.

---

Nitpick comments:
In `@src/modules/upload/index.js`:
- Around line 485-487: The function removeFileToUploadQueue currently uses a
compact one-line arrow that Prettier flagged; refactor it into a multi-line
arrow function to improve formatting and readability: locate export const
removeFileToUploadQueue and expand the async dispatch => block so the dispatch({
type: RECEIVE_UPLOAD_SUCCESS, fileId: fileId ?? file.name, file, isUpdate: true
}) call is on its own line(s) with proper indentation and trailing semicolon,
preserving the fallback behavior (fileId ?? file.name) and the action type
RECEIVE_UPLOAD_SUCCESS.
- Line 225: The inline dispatch call dispatch({ type: RECEIVE_UPLOAD_SUCCESS,
fileId, file, uploadedItem: newDir }) is flagged by ESLint/Prettier for
formatting; reformat the object literal passed to dispatch (the call in which
RECEIVE_UPLOAD_SUCCESS, fileId, file, and uploadedItem: newDir are used) into a
properly indented multi-line object with each property on its own line and
appropriate trailing commas to satisfy the project's linting rules.

In `@src/modules/upload/index.spec.js`:
- Line 679: The inline object passed to queue in the test is currently on one
line (const result3 = queue(result2, { type: 'RECEIVE_UPLOAD_ERROR', fileId,
file })) and needs to be formatted across multiple lines to satisfy
ESLint/Prettier; update the call to queue(result2, { ... }) so the object
properties (type, fileId, file) are each on their own lines (and keep result3
and result2 identifiers unchanged) ensuring commas and indentation follow the
project's formatting rules.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0c5b1bce-0c0f-4212-9847-ed698d27e06f

📥 Commits

Reviewing files that changed from the base of the PR and between 548f0bc and 9192bba.

📒 Files selected for processing (2)
  • src/modules/upload/index.js
  • src/modules/upload/index.spec.js

- Fix Prettier formatting violations (line wrapping)
- Use optional chaining in itemInitialState to handle directory entries
  where file is null: item.file?.name ?? item.entry?.name

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
codescene-delta-analysis[bot]

This comment was marked as outdated.

@bundlemon
Copy link
Copy Markdown

bundlemon bot commented Apr 6, 2026

BundleMon

Files updated (2)
Status Path Size Limits
public/static/js/public.(hash).js
141.3KB (+204B +0.14%) -
static/js/main.(hash).js
167.6KB (+204B +0.12%) -
Unchanged files (19)
Status Path Size Limits
static/js/(chunkId).(hash).js
1.07MB -
public/static/js/(chunkId).(hash).js
1.01MB -
static/js/cozy.(hash).js
894.94KB -
public/static/js/cozy.(hash).js
758.89KB -
(hash).js
336.11KB -
public/(hash).js
336.11KB -
services/qualificationMigration.js
283.13KB -
services/dacc.js
262.86KB -
public/static/js/lib-react.(hash).js
43.88KB -
static/js/lib-react.(hash).js
43.88KB -
public/static/css/cozy.(hash).css
33.78KB -
static/css/cozy.(hash).css
33.78KB -
public/static/js/lib-router.(hash).js
21.86KB -
static/js/lib-router.(hash).js
21.86KB -
static/css/main.(hash).css
17.04KB -
public/static/css/public.(hash).css
6.76KB -
manifest.webapp
3.04KB -
index.html
702B -
assets/manifest.json
185B -

Total files change +408B +0.01%

Groups updated (1)
Status Path Size Limits
**/*.js
7.37MB (+408B +0.01%) -
Unchanged groups (2)
Status Path Size Limits
**/*.{png,svg,ico}
2.19MB -
**/*.css
128.38KB -

Final result: ✅

View report in BundleMon website ➡️


Current branch size history | Target branch size history

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/modules/upload/index.js`:
- Line 160: The reducer matches queue items by action.fileId but UploadUtils.ts
dispatches RECEIVE_UPLOAD_SUCCESS and RECEIVE_UPLOAD_ERROR without fileId, so
add fileId to those dispatched actions; in UploadUtils.ts update the dispatch
calls for RECEIVE_UPLOAD_SUCCESS and RECEIVE_UPLOAD_ERROR to include fileId
(e.g. fileId: file.fileId or the same identifier used when the upload was
enqueued) so action.fileId matches the reducer's comparison. Ensure the
dispatched payload keys exactly match the reducer (action.fileId) so the item(i,
action) branch runs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 05c17e4f-854c-40e9-b746-3a123c7f2757

📥 Commits

Reviewing files that changed from the base of the PR and between 9192bba and 6dba033.

📒 Files selected for processing (2)
  • src/modules/upload/index.js
  • src/modules/upload/index.spec.js
✅ Files skipped from review due to trivial changes (1)
  • src/modules/upload/index.spec.js

The Flagship upload path (UploadUtils.ts) dispatches RECEIVE_UPLOAD_SUCCESS
and RECEIVE_UPLOAD_ERROR without fileId. The reducer now falls back to
matching on file.name when fileId is absent, ensuring these dispatches
still update the correct queue item.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@Crash-- Crash-- force-pushed the fix/upload-queue-fileId-identity branch from b360e9d to 20a8482 Compare April 7, 2026 03:29
codescene-delta-analysis[bot]

This comment was marked as outdated.

Extract getUploadErrorStatus() and handleConflictOverwrite() to lower
cyclomatic complexity flagged by CodeScene.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Crash-- Crash-- force-pushed the fix/upload-queue-fileId-identity branch from 20a8482 to fa56779 Compare April 7, 2026 03:40
codescene-delta-analysis[bot]

This comment was marked as outdated.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/modules/upload/index.js`:
- Around line 56-59: itemInitialState currently falls back to
file.name/entry.name which allows collisions; ensure the enqueueing code
(extractFilesEntries and UploadUtils) populates a stable item.fileId before
dispatching ADD_TO_UPLOAD_QUEUE instead of relying on itemInitialState fallback.
Fix by generating/assigning a deterministic unique id (e.g., UUID or
content-based hash or monotonic counter) for each file/entry when creating the
item in extractFilesEntries / the UploadUtils enqueue path and set item.fileId
there so ADD_TO_UPLOAD_QUEUE receives items with a stable fileId. Ensure the
generated id is used by itemInitialState if present so identical basenames no
longer collide.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3889db3e-308a-4aa7-b165-956105405726

📥 Commits

Reviewing files that changed from the base of the PR and between b360e9d and 20a8482.

📒 Files selected for processing (1)
  • src/modules/upload/index.js

codescene-delta-analysis[bot]

This comment was marked as outdated.

extractFilesEntries now sets fileId from entry.fullPath, and
generateForQueue uses file.filePath for Flagship uploads.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Crash-- Crash-- force-pushed the fix/upload-queue-fileId-identity branch from 5546e10 to 133e44b Compare April 7, 2026 04:15
Copy link
Copy Markdown

@codescene-delta-analysis codescene-delta-analysis bot left a comment

Choose a reason for hiding this comment

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

Code Health Improved (1 files improve in Code Health)

Gates Passed
3 Quality Gates Passed

See analysis details in CodeScene

View Improvements
File Code Health Impact Categories Improved
index.js 8.37 → 8.79 Complex Method

Quality Gate Profile: The Bare Minimum
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

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