Fix generic error for oversized MCP file uploads#1193
Conversation
|
Claude finished @ishaanxgupta's task in 1m 24s —— View job Review Complete
Summary: Reviewed the oversized file upload error handling changes. No bugs, security issues, or logic errors found. The file size calculation correctly accounts for base64 inflation and the JSON-RPC envelope. The Graphite style comments about function declarations have been addressed in the latest commit. Score: 10/10 — Clean fix, ready to ship. |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
supermemory-mcp | 521db2b | Jul 04 2026, 02:49 PM |
There was a problem hiding this comment.
Overview: This PR fixes two UX issues in the MCP widget: showing friendly errors for oversized file uploads (instead of generic "something went wrong"), and returning a properly typed ViewMessage from fetch-graph-data so the widget renders the graph view instead of "unrecognized response."
Issues found: None — this looks good to ship.
Details:
fetch-graph-data.ts:
- Correctly returns a
ViewMessagewithview: "graph"discriminant instead of raw API response - The
containerTagis optional in the type (containerTag?: string), so passingeffectiveTag(which could be undefined) is type-safe - Text content now provides a human-readable summary instead of raw JSON
Upload.tsx:
- File size limit calculation is conservative and correct:
((4 MiB - 64 KiB) * 3/4) ≈ 2.95 MB, properly accounting for base64 inflation (~4/3) and the JSON-RPC envelope - Client-side validation prevents oversized uploads before they're attempted
- The regex
/413|too large|payload/ifor detecting transport errors is broad but safe — worst case it shows a size-related error for a non-size issue, which is better than a generic "Upload failed" - The
filereference in the catch block is captured in theuseCallbackclosure after the null check, so accessingfile.sizeis safe
Score: 10/10
Clean fix for real UX issues with proper typing and defensive error handling.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
supermemory-app | 521db2b | Commit Preview URL Branch Preview URL |
Jul 04 2026, 02:49 PM |
31f77a7 to
3a02393
Compare
500a4b5 to
df671c6
Compare
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
How to use the Graphite Merge QueueAdd the label Main to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
There was a problem hiding this comment.
Overview: This PR fixes two UX issues in the MCP widget: showing friendly errors for oversized file uploads (instead of generic "something went wrong"), and returning a properly typed ViewMessage from fetch-graph-data so the widget renders the graph view instead of "unrecognized response."
Issues found: None — this looks good to ship.
Details:
fetch-graph-data.ts:
- Correctly returns a
ViewMessagewithview: "graph"discriminant instead of raw API response - The
containerTagis optional in the type (containerTag?: string), so passingeffectiveTag(which could be undefined) is type-safe - Text content now provides a human-readable summary instead of raw JSON
Upload.tsx:
- File size limit calculation is conservative and correct:
((4 MiB - 64 KiB) * 3/4) ≈ 2.95 MB, properly accounting for base64 inflation (~4/3) and the JSON-RPC envelope - Client-side validation prevents oversized uploads before they're attempted
- The regex
/413|too large|payload/ifor detecting transport errors is broad but safe — worst case it shows a size-related error for a non-size issue, which is better than a generic "Upload failed" - The
filereference in the catch block is captured in theuseCallbackclosure after the null check, so accessingfile.sizeis safe
Score: 10/10
Clean fix for real UX issues with proper typing and defensive error handling.
3a02393 to
f7fc662
Compare
There was a problem hiding this comment.
Overview: This PR fixes UX issues in the Upload widget by showing friendly errors for oversized file uploads and properly handling transport-level 413 errors.
Issues found: None — this looks good to ship.
Details:
- File size limit calculation is correct:
((4 MiB - 64 KiB) * 3/4) ≈ 2.95 MB, properly accounting for base64 inflation (~4/3) and the JSON-RPC envelope - Client-side validation in
handleFileSelectprevents oversized uploads before they're attempted - The
filereference in the catch block is safe — it's captured in the closure after the null check at line 86, sofile.sizeaccess is guaranteed valid - The regex
/413|too large|payload/ifor detecting transport errors is broad but safe — worst case it shows a size-related error for a non-size issue, which is better than a generic "Upload failed" - Error display includes
role="alert"for accessibility
Score: 10/10
Clean fix for real UX issues with proper typing and defensive error handling.
| const FILE_TOO_LARGE_MESSAGE = (size: number) => | ||
| `This file is ${formatFileSize(size)}. The maximum upload size is ${formatFileSize(MAX_UPLOAD_BYTES)} — please choose a smaller file.` |
There was a problem hiding this comment.
The rule 'Use function declarations over function expressions' is violated here. FILE_TOO_LARGE_MESSAGE is defined as a const arrow function expression:
const FILE_TOO_LARGE_MESSAGE = (size: number) =>
`This file is ...`This should be rewritten as a function declaration:
function fileTooLargeMessage(size: number): string {
return `This file is ${formatFileSize(size)}. The maximum upload size is ${formatFileSize(MAX_UPLOAD_BYTES)} — please choose a smaller file.`
}| const FILE_TOO_LARGE_MESSAGE = (size: number) => | |
| `This file is ${formatFileSize(size)}. The maximum upload size is ${formatFileSize(MAX_UPLOAD_BYTES)} — please choose a smaller file.` | |
| function fileTooLargeMessage(size: number): string { | |
| return `This file is ${formatFileSize(size)}. The maximum upload size is ${formatFileSize(MAX_UPLOAD_BYTES)} — please choose a smaller file.` | |
| } | |
Spotted by Graphite (based on custom rule: TypeScript style guide (Google))
Is this helpful? React 👍 or 👎 to let us know.
| const handleFileSelect = (selected: File) => { | ||
| if (selected.size > MAX_UPLOAD_BYTES) { | ||
| log( | ||
| "warning", | ||
| `[upload] rejected oversized file: ${selected.name} (${selected.size}B > ${MAX_UPLOAD_BYTES}B)`, | ||
| ) | ||
| setFileError(FILE_TOO_LARGE_MESSAGE(selected.size)) | ||
| setFile(null) | ||
| return | ||
| } | ||
| setFileError(null) | ||
| setFile(selected) | ||
| } |
There was a problem hiding this comment.
The rule 'Use function declarations over function expressions' is violated here. handleFileSelect is defined as a const arrow function expression:
const handleFileSelect = (selected: File) => {
...
}Since this is a named function (not a concise callback), it should be rewritten as a function declaration:
function handleFileSelect(selected: File) {
...
}| const handleFileSelect = (selected: File) => { | |
| if (selected.size > MAX_UPLOAD_BYTES) { | |
| log( | |
| "warning", | |
| `[upload] rejected oversized file: ${selected.name} (${selected.size}B > ${MAX_UPLOAD_BYTES}B)`, | |
| ) | |
| setFileError(FILE_TOO_LARGE_MESSAGE(selected.size)) | |
| setFile(null) | |
| return | |
| } | |
| setFileError(null) | |
| setFile(selected) | |
| } | |
| function handleFileSelect(selected: File) { | |
| if (selected.size > MAX_UPLOAD_BYTES) { | |
| log( | |
| "warning", | |
| `[upload] rejected oversized file: ${selected.name} (${selected.size}B > ${MAX_UPLOAD_BYTES}B)`, | |
| ) | |
| setFileError(FILE_TOO_LARGE_MESSAGE(selected.size)) | |
| setFile(null) | |
| return | |
| } | |
| setFileError(null) | |
| setFile(selected) | |
| } | |
Spotted by Graphite (based on custom rule: TypeScript style guide (Google))
Is this helpful? React 👍 or 👎 to let us know.
SummaryReviewed the live PR diff for Verdict✅ Reviewed — no issues found. The implementation is scoped and handles the reviewed oversized-file states appropriately. |
TestingValidated the live PR diff for Commands run: cd /code/supermemoryai/supermemory/apps/mcp
bun run dev:widget --host 0.0.0.0
__VITE_ADDITIONAL_SERVER_ALLOWED_HOSTS=gfs7r8i3m2jf.preview.us1.vorflux.com bun run dev:widget --host 0.0.0.0
npx agent-browser upload "input[accept=\".txt,.pdf,.png,.jpg,.jpeg,.mp4\"]" /var/tmp/testing_upload_pr1193/oversized-3_1mb.txt --args "--no-sandbox"
npx agent-browser upload "input[accept=\".txt,.pdf,.png,.jpg,.jpeg,.mp4\"]" /var/tmp/testing_upload_pr1193/small-valid.txt --args "--no-sandbox"
bunx biome ci apps/mcp/src/widget/views/Upload.tsx
cd apps/mcp && bun run check-typesResult: Verdict
Attached Images and Videos |
df671c6 to
e706a13
Compare
acd2fea to
df671c6
Compare
The MCP transport rejects JSON-RPC bodies over 4 MiB with a bare 413, so large file uploads died with a generic "Upload failed" widget error. The upload widget now rejects oversized files at selection time with the size limit spelled out, advertises the limit in the dropzone copy, and maps any transport 413 that still occurs to the same friendly message. Co-authored-by: Cursor <cursoragent@cursor.com>
Address Graphite style review on Upload.tsx. Co-authored-by: Cursor <cursoragent@cursor.com>
f7fc662 to
521db2b
Compare
There was a problem hiding this comment.
Overview: This PR improves UX by showing friendly error messages for oversized file uploads instead of generic "Upload failed" errors.
Issues found: None — this looks good to ship.
Details:
- File size limit calculation is correct:
((4 MiB - 64 KiB) * 3/4) ≈ 2.95 MB, properly accounting for base64 inflation and JSON-RPC envelope - Client-side validation in
handleFileSelectprevents oversized uploads before network requests - The
filereference in error handlers is safe — captured after the null check at line 87 - The regex
/413|too large|payload/ifor transport errors is intentionally broad — worst case shows a size-related message for a non-size issue, better than a generic failure - Error display includes
role="alert"for accessibility - The Graphite style comments about function declarations have been addressed in the latest commit
Score: 10/10
Clean fix for a real UX issue with correct math and defensive error handling.










Summary
agentsSDK) rejects JSON-RPC bodies over 4 MiB with a bare HTTP 413 before the tool ever runs, so uploading a large file showed a generic "Something went wrong / Upload failed" in the widget.Stacked on #1192 → #1189 → #1120.