Skip to content

Add File Validation, Error Handling and prevent duplicates file upload to FileUploader (Prevent Invalid Uploads)#7

Open
advay-demo wants to merge 3 commits into
mainfrom
fix/file-validation-uploader
Open

Add File Validation, Error Handling and prevent duplicates file upload to FileUploader (Prevent Invalid Uploads)#7
advay-demo wants to merge 3 commits into
mainfrom
fix/file-validation-uploader

Conversation

@advay-demo

@advay-demo advay-demo commented Feb 15, 2026

Copy link
Copy Markdown
Collaborator

This PR improves the reliability and user experience of the file upload workflow by adding proper file-type validation, error messaging, and safeguards against invalid processing.

Previously, the uploader accepted files based only on filename/extension, allowing incorrectly renamed files (e.g., .txt → .pdf) to be added without feedback. This caused silent failures during processing.

The updated implementation validates files using MIME type checks, prevents invalid files from entering the workflow, and provides clear user-facing error messages.

🔧 Changes Made
✅ Validation Improvements

Added tool-aware file validation:

PDF tools accept only application/pdf

Image tools accept only valid image/* types

Prevents renamed or unsupported files from being uploaded.

✅ User Experience Fixes

Added visible error messages for invalid uploads.

Eliminated silent ⚠ failures with no explanation.

Reset error state when files are removed.

✅ Stability Enhancements

Prevented processing when no valid files exist.

Fixed JSX rendering issue that could crash the component.

Reordered helper functions to avoid runtime reference issues.

✅ Code Quality

Centralized validation logic (validateFileForTool).

Improved state handling for invalid vs. accepted files.

Ensured consistent behavior across all tools (PDF + Image).

🐞 Bug Fixed

Issue: Invalid files were accepted without validation or feedback.
Impact: Processing errors and confusing UX.
Resolution: Added MIME-based validation and clear error messaging.

🧪 Testing Performed

Uploaded renamed fake PDFs → correctly rejected.

Uploaded valid PDFs/images → processed successfully.

Removed invalid files → error state cleared.

Tested drag/drop and file selector flows.

Verified processing disabled when no valid files present.

🚀 Result

This change makes the upload system safer, more predictable, and production-ready by enforcing input validation and improving feedback to users.

Summary by CodeRabbit

  • New Features

    • Visual error banner and styled error messages for file uploads.
    • File validation and duplicate detection to prevent incompatible or repeated uploads.
    • Unified upload flow with clearer per-file statuses and streamlined processing and download actions.
  • Bug Fixes

    • Improved error handling and clearer recovery when processing fails.
  • Style

    • Redesigned, simplified file uploader layout and controls for better usability.

… Uploads)

This PR improves the reliability and user experience of the file upload workflow by adding proper file-type validation, error messaging, and safeguards against invalid processing.

Previously, the uploader accepted files based only on filename/extension, allowing incorrectly renamed files (e.g., .txt → .pdf) to be added without feedback. This caused silent failures during processing.

The updated implementation validates files using MIME type checks, prevents invalid files from entering the workflow, and provides clear user-facing error messages.

🔧 Changes Made
✅ Validation Improvements

Added tool-aware file validation:

PDF tools accept only application/pdf

Image tools accept only valid image/* types

Prevents renamed or unsupported files from being uploaded.

✅ User Experience Fixes

Added visible error messages for invalid uploads.

Eliminated silent ⚠ failures with no explanation.

Reset error state when files are removed.

✅ Stability Enhancements

Prevented processing when no valid files exist.

Fixed JSX rendering issue that could crash the component.

Reordered helper functions to avoid runtime reference issues.

✅ Code Quality

Centralized validation logic (validateFileForTool).

Improved state handling for invalid vs. accepted files.

Ensured consistent behavior across all tools (PDF + Image).

🐞 Bug Fixed

Issue: Invalid files were accepted without validation or feedback.
Impact: Processing errors and confusing UX.
Resolution: Added MIME-based validation and clear error messaging.

🧪 Testing Performed

Uploaded renamed fake PDFs → correctly rejected.

Uploaded valid PDFs/images → processed successfully.

Removed invalid files → error state cleared.

Tested drag/drop and file selector flows.

Verified processing disabled when no valid files present.

🚀 Result

This change makes the upload system safer, more predictable, and production-ready by enforcing input validation and improving feedback to users.
@coderabbitai

coderabbitai Bot commented Feb 15, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Updated service worker precache revision for index.html. Added .upload-error CSS. Reworked FileUploader: centralized validation, unified add/process flows, per-file statuses and deduplication, errorMessage banner UI, simplified file list and download/remove handling.

Changes

Cohort / File(s) Summary
Service Worker Manifest
dev-dist/sw.js
Updated precache manifest entry for index.html revision from 0.sskc1m612v8 to 0.9sdrrlu31pk.
File Uploader Styling
src/components/ui/FileUploader.css
Added .upload-error CSS class for error banner styling (margin, padding, border-radius, background #ffe6e6, text color #b30000, flex layout).
File Uploader Component
src/components/ui/FileUploader.jsx
Major overhaul: added validation helpers (isValidPDF, isValidImage, validateFileForTool), consolidated addFiles (validation, dedupe, ID/size formatting), unified drag/drop and input handling, per-file status lifecycle, centralized processFiles routing (pdf-merge, pdf-split, image-*), error banner state, simplified UI and download/remove logic.

Sequence Diagram

sequenceDiagram
    actor User
    participant FileUploader
    participant Validator
    participant Processor
    participant Results

    User->>FileUploader: select or drop files
    FileUploader->>Validator: validateFileForTool(file, tool)
    alt valid
        Validator-->>FileUploader: valid
        FileUploader->>FileUploader: assign ID, format size, add to list
        FileUploader->>Processor: processFiles(files, tool)
        Processor->>Processor: route by tool type (pdf-merge / pdf-split / image-*)
        Processor->>Processor: set file status 'processing'
        Processor-->>Results: produce outputs
        Results-->>FileUploader: update status to 'completed' and provide results
        FileUploader->>User: show Download button
    else invalid
        Validator-->>FileUploader: invalid (reason)
        FileUploader->>FileUploader: set errorMessage
        FileUploader->>User: display error banner (.upload-error)
    end
    alt processing error
        Processor-->>FileUploader: error
        FileUploader->>FileUploader: set generic errorMessage
        FileUploader->>User: display error banner
    end
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I nibbled bugs and hopped around,

Files sorted neat, no duplicates found,
Banners bloom when errors call,
Processing hums — I love it all,
Click download — I bounce with glee!

🚥 Pre-merge checks | ✅ 2 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (37 files):

⚔️ .env.example (content)
⚔️ .github/workflows/firebase-deploy.yml (content)
⚔️ README.md (content)
⚔️ eslint.config.js (content)
⚔️ firestore.rules (content)
⚔️ package-lock.json (content)
⚔️ src/app/App.jsx (content)
⚔️ src/components/layout/Footer.css (content)
⚔️ src/components/layout/Footer.jsx (content)
⚔️ src/components/layout/Header.css (content)
⚔️ src/components/layout/Header.jsx (content)
⚔️ src/components/meta/SeoHead.jsx (content)
⚔️ src/components/ui/FileUploader.css (content)
⚔️ src/components/ui/FileUploader.jsx (content)
⚔️ src/components/ui/ToolCard.css (content)
⚔️ src/components/ui/ToolCard.jsx (content)
⚔️ src/contexts/AuthContext.jsx (content)
⚔️ src/data/toolsData.js (content)
⚔️ src/features/about/AboutPage.jsx (content)
⚔️ src/features/auth/AuthPage.css (content)
⚔️ src/features/auth/AuthPage.jsx (content)
⚔️ src/features/home/HomePage.css (content)
⚔️ src/features/home/HomePage.jsx (content)
⚔️ src/features/legal/LegalPages.jsx (content)
⚔️ src/features/pricing/PricingPage.css (content)
⚔️ src/features/pricing/PricingPage.jsx (content)
⚔️ src/features/profile/ProfilePage.css (content)
⚔️ src/features/profile/ProfilePage.jsx (content)
⚔️ src/features/projects/ProjectsPage.jsx (content)
⚔️ src/features/tools/ToolDetailPage.css (content)
⚔️ src/features/tools/ToolDetailPage.jsx (content)
⚔️ src/locales/en.json (content)
⚔️ src/services/feedbackService.js (content)
⚔️ src/services/imageService.js (content)
⚔️ src/services/pdfService.js (content)
⚔️ src/services/userService.js (content)
⚔️ src/styles/index.css (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main changes: file validation, error handling, and duplicate file prevention in FileUploader, which aligns with the comprehensive modifications across validation logic, error messaging, and file deduplication shown in the changeset.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/file-validation-uploader
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch fix/file-validation-uploader
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In `@src/components/ui/FileUploader.jsx`:
- Around line 186-201: The remove button in the FileUploader.jsx file (inside
the files.map render where removeFile(file.id) is called for each .file-item) is
missing the intended styling class; update the button element that invokes
removeFile to include the existing CSS class (e.g., "remove-btn") so it uses the
project's remove button styles and matches other file-item controls.
- Around line 160-165: The filename generation truncates at the first dot
because processedResults.forEach uses res.originalName.split('.')[0]; update the
logic used before calling imageService.downloadBlob so it takes the substring
after the last dot (e.g., find lastIndexOf('.') and slice) to preserve
multiple-dot filenames when constructing `${baseName}_forge.${ext}`; modify the
code in the branch where tool.id.startsWith('image') (inside
processedResults.forEach and the imageService.downloadBlob call) to compute
baseName using lastIndexOf rather than split.
- Around line 154-158: The forEach callback in FileUploader.jsx currently uses
an implicit return `(data, index) => pdfService.downloadPDF(...)`, triggering
the lint error; change the callback to a block body to avoid returning a value
by replacing the arrow callback with a braced function body for
processedResults.forEach so it calls pdfService.downloadPDF(data, `page_${index
+ 1}.pdf`) inside braces (no return). Update the code path where tool.id ===
'pdf-split' and the processedResults.forEach invocation to use the braced
callback form.
- Around line 16-22: formatFileSize can compute an index i >= sizes.length for
very large byte values, causing sizes[i] to be undefined; update the function
(formatFileSize) to clamp i to a valid range (e.g., i = Math.min(i, sizes.length
- 1)) or extend the sizes array to include larger units before using sizes[i],
so the computed unit is always defined and the returned string never contains
"NaN undefined".
- Around line 114-135: The current image handling loop unconditionally calls
imageService.convertImage for any tool.id starting with 'image', which bypasses
tool-specific handlers (e.g., imageService.resizeImage) and will crash for tools
without implementations; change the loop in the image-* branch to dispatch based
on tool.id (use a switch or mapping) and call the correct service method (e.g.,
imageService.resizeImage for 'image-resize', imageService.convertImage only for
convert/compress cases), update the per-file status with setFiles the same way,
push the returned result into results, and for tools without a service method
set an error/failed status or a clear not-implemented result before calling
setProcessedResults so unimplemented tools fail gracefully instead of throwing.
🧹 Nitpick comments (3)
src/components/ui/FileUploader.css (1)

212-222: Hardcoded colors break theme consistency.

The rest of this stylesheet uses CSS custom properties (var(--primary-500), var(--text-primary), etc.), but .upload-error hardcodes #ffe6e6 and #b30000. This will look out of place in a dark theme or any alternate color scheme.

Consider introducing error-specific CSS variables (e.g., --error-bg, --error-text) or reusing existing ones.

♻️ Suggested change
 .upload-error {
     margin-bottom: 12px;
     padding: 10px;
     border-radius: 6px;
-    background: `#ffe6e6`;
-    color: `#b30000`;
+    background: var(--error-bg, `#ffe6e6`);
+    color: var(--error-text, `#b30000`);
     display: flex;
     align-items: center;
     gap: 8px;
     font-size: 14px;
 }
src/components/ui/FileUploader.jsx (2)

37-65: addFiles clears the error when all files in one batch are valid, even if a prior batch had invalid files still worth noting.

Current behavior: if a user drops 1 invalid file (error shown), then drops 1 valid file, the error message is cleared (line 58) even though the invalid file was never accepted. This is arguably fine UX (the latest action succeeded), but worth confirming that's the intent.

Also, Math.random().toString(36).substr(2, 9) on line 44 uses the deprecated substr method.

♻️ Minor: prefer `substring` over deprecated `substr`
-                    id: Math.random().toString(36).substr(2, 9),
+                    id: Math.random().toString(36).substring(2, 11),

177-177: Add accept attribute to the file input for better UX and first-pass filtering.

The <input type="file"> lacks an accept attribute, so the OS file picker shows all files. Since validation already rejects wrong types, adding accept gives users immediate visual guidance and reduces invalid selections.

Also, multiple is always set, but pdf-split only uses the first file. Consider making it conditional.

♻️ Suggested improvement
-            <input type="file" multiple hidden ref={fileInputRef} onChange={handleFileSelect} />
+            <input
+                type="file"
+                multiple={tool.id !== 'pdf-split'}
+                accept={tool.id.startsWith('pdf') ? 'application/pdf' : tool.id.startsWith('image') ? 'image/*' : undefined}
+                hidden
+                ref={fileInputRef}
+                onChange={handleFileSelect}
+            />

Comment thread src/components/ui/FileUploader.jsx
Comment on lines +114 to 135
else if (tool.id.startsWith('image')) {
const results = [];

for (let i = 0; i < files.length; i++) {
setFiles(prev => prev.map((f, idx) => idx === i ? { ...f, status: 'processing' } : f));
setFiles(prev => prev.map((f, idx) =>
idx === i ? { ...f, status: 'processing' } : f
));

const format = tool.id === 'image-convert' ? 'image/png' : 'image/jpeg';
const quality = tool.id === 'image-compress' ? 0.6 : 0.9;

const result = await imageService.convertImage(files[i].file, format, quality);

results.push({ blob: result, originalName: files[i].name, format });
setFiles(prev => prev.map((f, idx) => idx === i ? { ...f, status: 'completed' } : f));

setFiles(prev => prev.map((f, idx) =>
idx === i ? { ...f, status: 'completed' } : f
));
}

setProcessedResults(results);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for image-related tool IDs in the codebase
rg -n --type=js --type=jsx "image-" -g '!node_modules' -g '!dist' | head -50

Repository: Sumit-5002/Anyfileforge

Length of output: 94


🏁 Script executed:

#!/bin/bash
# Search for image-related tool IDs without jsx file type
rg -n "image-" -g '!node_modules' -g '!dist' | head -100

Repository: Sumit-5002/Anyfileforge

Length of output: 2915


🏁 Script executed:

#!/bin/bash
# Find imageService implementation to see what methods are available
fd -type f -name "*imageService*" -o -name "*image-service*" | head -20

Repository: Sumit-5002/Anyfileforge

Length of output: 237


🏁 Script executed:

#!/bin/bash
# Search for imageService implementation
rg -l "imageService" -g '!node_modules' | head -20

Repository: Sumit-5002/Anyfileforge

Length of output: 130


🏁 Script executed:

#!/bin/bash
# Read imageService.js to see available methods
cat -n src/services/imageService.js

Repository: Sumit-5002/Anyfileforge

Length of output: 4538


🏁 Script executed:

#!/bin/bash
# Read FileUploader.jsx to see the full context and error handling
sed -n '100,150p' src/components/ui/FileUploader.jsx | cat -n

Repository: Sumit-5002/Anyfileforge

Length of output: 2406


Image processing unconditionally calls convertImage for all image- tools, bypassing tool-specific handlers.*

The code at lines 114–135 routes every image-* tool to imageService.convertImage() with only image-compress and the non-existent image-convert receiving special handling. However, 11 image tools are defined in toolsData.js:

  • image-resize, image-crop, image-rotate, image-upscale, image-remove-bg, image-blur-face, image-editor, image-watermark, image-meme have no corresponding service methods
  • image-resize has imageService.resizeImage() available but will never be called

Tools without implementations will fail at runtime. The code needs to dispatch each tool to its appropriate handler instead of forcing all through format conversion.

🤖 Prompt for AI Agents
In `@src/components/ui/FileUploader.jsx` around lines 114 - 135, The current image
handling loop unconditionally calls imageService.convertImage for any tool.id
starting with 'image', which bypasses tool-specific handlers (e.g.,
imageService.resizeImage) and will crash for tools without implementations;
change the loop in the image-* branch to dispatch based on tool.id (use a switch
or mapping) and call the correct service method (e.g., imageService.resizeImage
for 'image-resize', imageService.convertImage only for convert/compress cases),
update the per-file status with setFiles the same way, push the returned result
into results, and for tools without a service method set an error/failed status
or a clear not-implemented result before calling setProcessedResults so
unimplemented tools fail gracefully instead of throwing.

Comment thread src/components/ui/FileUploader.jsx Outdated
Comment thread src/components/ui/FileUploader.jsx Outdated
Comment thread src/components/ui/FileUploader.jsx
Added duplicate file detection in FileUploader to prevent users from uploading the same file multiple times.
Files are now validated using name, size, and lastModified metadata before being added.
Improved reliability of processing tools and added user feedback when duplicates are ignored.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@src/components/ui/FileUploader.jsx`:
- Around line 128-133: The pdf-split branch only processes files[0] which
ignores additional uploads; update the pdf-split handling in FileUploader.jsx so
it processes all uploaded files (or enforces single-file input), e.g., map over
the files array and call pdfService.splitPDF for each (use Promise.all to run
concurrently), aggregate/flatten the results and call setProcessedResults with
the combined output, and update setFiles to mark each file's status to
'completed' (or per-file status if individual results/errors occur); change
logic around tool.id === 'pdf-split', files, pdfService.splitPDF,
setProcessedResults and setFiles accordingly.
- Around line 42-55: The duplicate-check only compares each incoming item
against the existing files state (`files`) and misses duplicates inside the same
`newFiles` batch; update the logic in the FileUploader component (where
`newFiles.forEach` runs) to also check against the in-progress `valid`
collection (or a local Set) so you skip adding a file that was already accepted
earlier in the same iteration—i.e., compute `alreadyExists` by testing both
`files` and `valid` (or `seenInBatch`) and push names to `duplicates` only when
truly new.
- Around line 112-114: The file input handler handleFileSelect currently calls
addFiles(Array.from(e.target.files)) but doesn’t reset the input value, so
re-selecting the same file won’t fire onChange; update handleFileSelect to read
files (guarding e.target and e.target.files), call addFiles with
Array.from(e.target.files), and then set e.target.value = '' (or null) to clear
the input so subsequent selection of the same file triggers onChange again.
- Around line 70-79: The current if / else if in the file uploader causes one
message to hide the other; update the logic around duplicates, invalid,
setErrorMessage to accumulate messages instead of using exclusive branches:
build a messages array (push duplicate and invalid messages using duplicates,
invalid, and tool.name as needed), then call setErrorMessage(messages.join(';
')) or clear it when empty; replace the existing if/else if/else block with this
combined-message approach so both duplicate and invalid feedback are shown.
🧹 Nitpick comments (1)
src/components/ui/FileUploader.jsx (1)

198-198: Consider adding an accept attribute to the file input for better UX.

The file picker currently shows all file types, relying solely on post-selection validation to reject invalid files. Adding an accept attribute would filter the picker natively, reducing user friction.

♻️ Proposed change
-            <input type="file" multiple hidden ref={fileInputRef} onChange={handleFileSelect} />
+            <input
+                type="file"
+                multiple
+                hidden
+                ref={fileInputRef}
+                onChange={handleFileSelect}
+                accept={tool.id.startsWith('pdf') ? 'application/pdf' : tool.id.startsWith('image') ? 'image/*' : undefined}
+            />

Comment thread src/components/ui/FileUploader.jsx
Comment thread src/components/ui/FileUploader.jsx
Comment on lines 112 to 114
const handleFileSelect = (e) => {
const selectedFiles = Array.from(e.target.files);
addFiles(selectedFiles);
};

const addFiles = (newFiles) => {
const fileObjects = newFiles.map((file) => ({
id: Math.random().toString(36).substr(2, 9),
file,
name: file.name,
size: formatFileSize(file.size),
status: 'ready'
}));
setFiles((prev) => [...prev, ...fileObjects]);
setProcessedResults([]);
};

const removeFile = (id) => {
setFiles((prev) => prev.filter((f) => f.id !== id));
setProcessedResults([]);
addFiles(Array.from(e.target.files));
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

File input value is not reset — re-selecting the same file after removal won't trigger onChange.

After a user removes a file and tries to re-add the same file via the file picker, the browser won't fire onChange because the input's value is unchanged. Reset e.target.value after reading the files.

🐛 Proposed fix
     const handleFileSelect = (e) => {
         addFiles(Array.from(e.target.files));
+        e.target.value = '';
     };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleFileSelect = (e) => {
const selectedFiles = Array.from(e.target.files);
addFiles(selectedFiles);
};
const addFiles = (newFiles) => {
const fileObjects = newFiles.map((file) => ({
id: Math.random().toString(36).substr(2, 9),
file,
name: file.name,
size: formatFileSize(file.size),
status: 'ready'
}));
setFiles((prev) => [...prev, ...fileObjects]);
setProcessedResults([]);
};
const removeFile = (id) => {
setFiles((prev) => prev.filter((f) => f.id !== id));
setProcessedResults([]);
addFiles(Array.from(e.target.files));
};
const handleFileSelect = (e) => {
addFiles(Array.from(e.target.files));
e.target.value = '';
};
🤖 Prompt for AI Agents
In `@src/components/ui/FileUploader.jsx` around lines 112 - 114, The file input
handler handleFileSelect currently calls addFiles(Array.from(e.target.files))
but doesn’t reset the input value, so re-selecting the same file won’t fire
onChange; update handleFileSelect to read files (guarding e.target and
e.target.files), call addFiles with Array.from(e.target.files), and then set
e.target.value = '' (or null) to clear the input so subsequent selection of the
same file triggers onChange again.

Comment thread src/components/ui/FileUploader.jsx
@advay-demo advay-demo changed the title Add File Validation & Error Handling to FileUploader (Prevent Invalid Uploads) Add File Validation, Error Handling and prevent duplicates file upload to FileUploader (Prevent Invalid Uploads) Feb 15, 2026
@Sumit-5002

Copy link
Copy Markdown
Owner

@advay-demo check the review by coderrabbit and solve ..

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/components/ui/FileUploader.jsx`:
- Line 136: The code uses inconsistent prefixes when checking tool IDs:
processFiles uses tool.id.startsWith('image') while handleDownload uses
tool.id.startsWith('image-'); update both checks to the same prefix (prefer
'image-' for clarity and to match handleDownload) so tools are treated
consistently; modify the startsWith call in processFiles (and any other
occurrences) to use 'image-' and ensure any related conditional logic in
processFiles and handleDownload remains aligned with the normalized prefix.
- Around line 26-33: The current validation (isValidPDF, isValidImage used by
validateFileForTool) relies on file.type which is provided by the browser and
can be spoofed; update validation to perform content-based checks by reading the
file's bytes: for PDFs read the first few bytes and ensure they match the PDF
magic header ("%PDF"), for images validate common magic numbers (e.g., JPEG
0xFFD8, PNG 0x89504E47, GIF "GIF87a"/"GIF89a") before returning true; keep the
existing file.type checks as a fast fallback but call new async validators
(e.g., isValidPDF -> isValidPDFContent, isValidImage -> isValidImageContent)
from validateFileForTool (which will need to handle/promote async) so renamed
fake files are rejected based on file content rather than extension alone.
- Around line 139-154: The loop updates file statuses using positional indices
which breaks if a file is removed during processing; change the processing loop
in FileUploader.jsx to capture each file's unique id (e.g., const fileId =
files[i].id) and use setFiles(prev => prev.map(f => f.id === fileId ? { ...f,
status: 'processing' } : f)) and similarly for the 'completed' update so you
match by file.id instead of idx===i; additionally, disable the remove button in
the JSX (the button handler referenced around the remove button) whenever any
file has status 'processing' (e.g., derive a isProcessing flag from files.some(f
=> f.status==='processing') and use it to disable the remove control) so users
cannot remove items mid-processing.
🧹 Nitpick comments (3)
src/components/ui/FileUploader.jsx (3)

37-85: Inconsistent indentation: function body is not indented within the component scope.

Lines 38–85 are flush-left while the rest of the component body uses 4-space indentation. This looks like a copy-paste artifact.


59-59: substr is deprecated — use substring instead.

String.prototype.substr is a legacy method. Replace with substring.

Proposed fix
-                id: Math.random().toString(36).substr(2, 9),
+                id: Math.random().toString(36).substring(2, 11),

199-199: Add accept attribute to file input for better UX.

The <input type="file"> has no accept attribute, so the file picker shows all file types. Adding a tool-appropriate accept filter would prevent users from selecting invalid files in the first place, reducing reliance on post-selection error messages.

Proposed fix
-            <input type="file" multiple hidden ref={fileInputRef} onChange={handleFileSelect} />
+            <input
+                type="file"
+                multiple
+                hidden
+                ref={fileInputRef}
+                onChange={handleFileSelect}
+                accept={tool.id.startsWith('pdf') ? 'application/pdf' : tool.id.startsWith('image') ? 'image/*' : undefined}
+            />

Comment thread src/components/ui/FileUploader.jsx
Comment thread src/components/ui/FileUploader.jsx
Comment on lines 139 to 154
for (let i = 0; i < files.length; i++) {
setFiles(prev => prev.map((f, idx) => idx === i ? { ...f, status: 'processing' } : f));
setFiles(prev => prev.map((f, idx) =>
idx === i ? { ...f, status: 'processing' } : f
));

const format = tool.id === 'image-convert' ? 'image/png' : 'image/jpeg';
const quality = tool.id === 'image-compress' ? 0.6 : 0.9;

const result = await imageService.convertImage(files[i].file, format, quality);

results.push({ blob: result, originalName: files[i].name, format });
setFiles(prev => prev.map((f, idx) => idx === i ? { ...f, status: 'completed' } : f));

setFiles(prev => prev.map((f, idx) =>
idx === i ? { ...f, status: 'completed' } : f
));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Index-based status updates will corrupt file statuses if files are removed during processing.

The remove button (line 219) is not disabled during processing, so users can remove files mid-loop. The setFiles updater on lines 140–142 and 151–153 uses idx === i to match files, but if a file is removed from state, indices shift and the wrong file gets updated.

Use file.id instead of positional index for status updates, and disable the remove button during processing.

Proposed fix — use ID-based matching and disable remove during processing

For the processing loop, capture the file ID and match on it:

             for (let i = 0; i < files.length; i++) {
+                const currentFileId = files[i].id;
                 setFiles(prev => prev.map((f, idx) =>
-                    idx === i ? { ...f, status: 'processing' } : f
+                    f.id === currentFileId ? { ...f, status: 'processing' } : f
                 ));

                 const format = tool.id === 'image-convert' ? 'image/png' : 'image/jpeg';
                 const quality = tool.id === 'image-compress' ? 0.6 : 0.9;

                 const result = await imageService.convertImage(files[i].file, format, quality);

                 results.push({ blob: result, originalName: files[i].name, format });

                 setFiles(prev => prev.map((f, idx) =>
-                    idx === i ? { ...f, status: 'completed' } : f
+                    f.id === currentFileId ? { ...f, status: 'completed' } : f
                 ));
             }

And in the JSX, disable the remove button while processing:

-                                <button onClick={() => removeFile(file.id)}>
+                                <button onClick={() => removeFile(file.id)} disabled={processing}>
🤖 Prompt for AI Agents
In `@src/components/ui/FileUploader.jsx` around lines 139 - 154, The loop updates
file statuses using positional indices which breaks if a file is removed during
processing; change the processing loop in FileUploader.jsx to capture each
file's unique id (e.g., const fileId = files[i].id) and use setFiles(prev =>
prev.map(f => f.id === fileId ? { ...f, status: 'processing' } : f)) and
similarly for the 'completed' update so you match by file.id instead of idx===i;
additionally, disable the remove button in the JSX (the button handler
referenced around the remove button) whenever any file has status 'processing'
(e.g., derive a isProcessing flag from files.some(f => f.status==='processing')
and use it to disable the remove control) so users cannot remove items
mid-processing.

@Sumit-5002 Sumit-5002 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@coderabbitai implement the chnage in the pr and review this pr

@Sumit-5002

Sumit-5002 commented Feb 16, 2026

Copy link
Copy Markdown
Owner

@jules implement change in this code and pr

@Sumit-5002

Copy link
Copy Markdown
Owner

@coderabbitai help

@coderabbitai

coderabbitai Bot commented Feb 17, 2026

Copy link
Copy Markdown
Contributor

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

CodeRabbit commands

These commands are invoked using PR/Issue comments.

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai evaluate custom pre-merge check --instructions <custom-checks-instructions> --name <custom-checks-title> [--mode <error|warning>] to validate the custom pre-merge checks instructions. Defaults to error when --mode is omitted.
    • @coderabbitai ignore pre-merge checks to override pre-merge checks and get an approval on PR.
    • @coderabbitai run pre-merge checks to run pre-merge checks on the pull request.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve to resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai generate configuration to create a PR that adds the current resolved configuration as .coderabbit.yaml (or show it if already present).
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit configuration file (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, support, documentation and community

  • Visit our status page to check the current availability of CodeRabbit.
  • Create a ticket on our support page for assistance with any issues or questions.
  • Visit our documentation site for detailed information on how to use CodeRabbit.
  • Join our Discord community to connect with other users and get help from the community.
  • Follow us on X/Twitter for updates and announcements.

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.

2 participants