Skip to content

fix(autox): fix 500 error after many duplicate file uploads#7220

Merged
openshift-merge-bot[bot] merged 6 commits intoopendatahub-io:mainfrom
daniduong:fix/autox-500-on-collision
Apr 17, 2026
Merged

fix(autox): fix 500 error after many duplicate file uploads#7220
openshift-merge-bot[bot] merged 6 commits intoopendatahub-io:mainfrom
daniduong:fix/autox-500-on-collision

Conversation

@daniduong
Copy link
Copy Markdown
Contributor

@daniduong daniduong commented Apr 13, 2026

https://redhat.atlassian.net/browse/RHOAIENG-58660

Description

This PR addresses error handling improvements in the S3 file upload collision resolution logic for AutoML and AutoRAG packages.

Changes Made

Backend (AutoML & AutoRAG BFFs):

  • ✅ Fixed HTTP status code when max collision attempts are exceeded: now returns 409 Conflict instead of 500 Internal Server Error
  • ✅ Added ErrMaxCollisionsExceeded sentinel error for proper error classification
  • ✅ Returns user-friendly error message: "unable to find unique filename after N attempts; try a different base name"
  • ✅ Added comprehensive tests for collision exhaustion scenarios in both packages

Frontend (AutoRAG):

  • ✅ Fixed error message propagation in useUploadToStorageMutation - now correctly extracts BFF error messages from JSON response
  • ✅ Enhanced user-facing error message to suggest renaming file when collision limit is reached

Why This Matters

Previously, when the BFF exhausted all attempts (default 10) to find a unique filename due to naming collisions (e.g., file.pdf, file-1.pdf, ... file-10.pdf all exist), it would:

  • Return 500 Internal Server Error (semantically incorrect - not a server malfunction)
  • Show generic error message to users
  • Frontend mutation handler would override the BFF error with "Upload failed with status 500"

Now:

  • Returns 409 Conflict (semantically correct - resource naming conflict)
  • Provides clear, actionable error message
  • Frontend correctly displays the BFF error message to users
  • Users receive helpful guidance to rename their file or clean up existing files

Future Consideration

A modal dialog to let users select a different filename when a collision occurs will be considered for future enhancement.

How Has This Been Tested?

Unit Tests

  • ✅ Added TestPostS3FileHandler_CollisionResolutionExhausted_Returns409 for both AutoML and AutoRAG
  • ✅ Tests verify 409 status code and error message content
  • ✅ All existing S3 handler tests pass

Manual Testing

  • Tested file upload with collision exhaustion scenario
  • Verified 409 error is returned
  • Verified user sees friendly error message in UI
Before After
Screen.Recording.2026-04-14.at.10.35.09.AM.mov
Screen.Recording.2026-04-14.at.10.30.59.AM.mov

Test Impact

  • New tests added: Yes - collision exhaustion tests for both packages
  • Tests pass: All Go BFF tests pass for automl and autorag
  • Coverage: Error handling paths are now covered

Request review criteria:

Self checklist (all need to be checked):

  • The developer has manually tested the changes and verified that the changes work
  • Testing instructions have been added in the PR body (for PRs involving changes that are not immediately obvious).
  • The developer has added tests or explained why testing cannot be added (unit or cypress tests for related changes)
  • The code follows our Best Practices (React coding standards, PatternFly usage, performance considerations)

If you have UI changes:

  • Included any necessary screenshots or gifs if it was a UI change.
  • Included tags to the UX team if it was a UI/UX change.

After the PR is posted & before it merges:

  • The developer has tested their solution on a cluster by using the image produced by the PR to main

Summary by CodeRabbit

Release Notes

Bug Fixes

  • Enhanced handling of duplicate filename conflicts during file uploads. Users now receive clear, actionable error messages guiding them to rename the file or remove similarly-named existing files instead of generic server errors.
  • Improved error messaging across file upload operations with server response details now surfaced to users in human-readable format.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added user-friendly error messages when S3 file uploads encounter filename collisions, with guidance to rename or delete similarly named files.
  • Bug Fixes

    • Improved S3 upload error handling to return appropriate 409 Conflict status for filename collision scenarios instead of generic server errors.
  • Tests

    • Added test coverage for filename collision exhaustion scenarios in S3 file uploads.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 13, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress This PR is in WIP state label Apr 13, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 13, 2026

📝 Walkthrough

Walkthrough

This pull request adds a sentinel error ErrMaxCollisionsExceeded in the S3 handlers for both automl and autorag BFFs and changes collision-exhaustion handling to return HTTP 409 Conflict instead of 500. Frontend upload logic and hooks were updated to parse BFF error payloads (including attaching statusCode to thrown Errors) and to display a specialized conflict message when a 409 collision is detected. Tests were added/updated across backend and frontend to cover the collision-exhaustion path. Several import/order cosmetic changes were applied in frontend components.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes


Actionable Issues

  1. XSS via displayed BFF error messages — CWE-79
  • Finding: Frontend extracts errorResponse?.error?.message and renders it in notifications without explicit sanitization. If the BFF message contains HTML/script, it may be injected into the DOM depending on the notification component.
  • Fix: Sanitize or escape error text before display (e.g., use an escaping utility or ensure notification API treats content as plain text). Alternatively, only display server-side error codes and map to client-side messages.
  1. Unbounded message length — CWE-400 (Denial of Service / Resource Exhaustion) / CWE-20
  • Finding: Extracted error messages are not validated or truncated; extremely long messages may degrade UX or resource usage.
  • Fix: Limit displayed message length (e.g., truncate to 256 chars with ellipsis) and log full messages server-side.
  1. Fragile substring-based collision detection — CWE-20 (Improper Input Validation)
  • Finding: Frontend detects filename-collision by substring matching (e.g., 'unique filename') which is brittle and can be spoofed or missed.
  • Fix: Rely on a structured machine-readable indicator from the BFF (e.g., error code field or well-known error type) rather than free-text matching. If not possible, match against a strict, canonical token inserted by the BFF.

Apply fixes above to ensure safe, robust client behavior when rendering and interpreting BFF error payloads.

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main fix: addressing the incorrect 500 error status code when S3 file uploads exceed max collision attempts.
Description check ✅ Passed PR description is well-structured, complete, and follows the template with all required sections properly addressed.

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


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.

@daniduong
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@daniduong daniduong changed the title fix(autox): address 500 for error handling fix(autox): fix 500 error after many duplicate file uploads Apr 13, 2026
Copy link
Copy Markdown
Contributor

@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 (1)
packages/automl/frontend/src/app/components/configure/AutomlConfigure.tsx (1)

345-352: Do not branch the upload UX on an English error substring.

includes('unique filename') couples this flow to one backend message. Any wording change or localization will silently drop the 409-specific guidance even though the API behavior is unchanged. Have the upload mutation expose a stable discriminator such as HTTP status or backend error code, and branch on that here instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/automl/frontend/src/app/components/configure/AutomlConfigure.tsx`
around lines 345 - 352, The current upload error handling in AutomlConfigure.tsx
branches on the English substring 'unique filename' (in the notification.error
call) which is brittle; instead change the upload mutation to return/throw a
stable discriminator (HTTP status or backend error code) and update the catch
logic in the upload handler to detect that discriminator (e.g.,
err.response?.status === 409 or err.code === 'FILENAME_CONFLICT') and only then
show the specific 409 guidance; otherwise show the generic errorMessage. Update
references in AutomlConfigure to use the mutation's stable error field and
change the isConflict check to use that field (not string.includes).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/autorag/frontend/src/app/hooks/mutations.ts`:
- Around line 112-120: The error handling collapses the BFF envelope into
Error(message) and trusts errorResponse?.error?.message is a string; change the
logic in the upload error branch that parses xhr.responseText so you validate
the parsed payload and preserve status/code: parse JSON into errorResponse,
confirm types (e.g., typeof errorResponse?.error?.message === "string"), then
construct and reject a richer Error that includes both a clear message and
preserves metadata (attach status/xhr.status and the parsed body or an errorCode
field to the thrown object or a custom Error instance) instead of only
reject(new Error(errorMessage)); ensure callers can inspect the status/code and
original parsed envelope.

---

Nitpick comments:
In `@packages/automl/frontend/src/app/components/configure/AutomlConfigure.tsx`:
- Around line 345-352: The current upload error handling in AutomlConfigure.tsx
branches on the English substring 'unique filename' (in the notification.error
call) which is brittle; instead change the upload mutation to return/throw a
stable discriminator (HTTP status or backend error code) and update the catch
logic in the upload handler to detect that discriminator (e.g.,
err.response?.status === 409 or err.code === 'FILENAME_CONFLICT') and only then
show the specific 409 guidance; otherwise show the generic errorMessage. Update
references in AutomlConfigure to use the mutation's stable error field and
change the isConflict check to use that field (not string.includes).
🪄 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: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 32e0f757-c916-443e-8b71-821046e59725

📥 Commits

Reviewing files that changed from the base of the PR and between 38e3af3 and 1f17fec.

📒 Files selected for processing (11)
  • packages/automl/bff/internal/api/s3_handler.go
  • packages/automl/bff/internal/api/s3_handler_test.go
  • packages/automl/frontend/src/app/components/configure/AutomlConfigure.tsx
  • packages/automl/frontend/src/app/components/configure/__tests__/AutomlConfigure.spec.tsx
  • packages/autorag/bff/internal/api/s3_handler.go
  • packages/autorag/bff/internal/api/s3_handler_test.go
  • packages/autorag/frontend/src/app/components/configure/AutoragConfigure.tsx
  • packages/autorag/frontend/src/app/components/configure/AutoragEvaluationSelect.tsx
  • packages/autorag/frontend/src/app/components/configure/__tests__/AutoragConfigure.spec.tsx
  • packages/autorag/frontend/src/app/components/configure/__tests__/AutoragEvaluationSelect.spec.tsx
  • packages/autorag/frontend/src/app/hooks/mutations.ts

Comment thread packages/autorag/frontend/src/app/hooks/mutations.ts
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.80%. Comparing base (b5a4f24) to head (79b1a0f).
⚠️ Report is 50 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #7220      +/-   ##
==========================================
- Coverage   64.82%   64.80%   -0.02%     
==========================================
  Files        2441     2441              
  Lines       76004    75996       -8     
  Branches    19159    19158       -1     
==========================================
- Hits        49266    49248      -18     
- Misses      26738    26748      +10     

see 16 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b5a4f24...79b1a0f. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@daniduong daniduong marked this pull request as ready for review April 14, 2026 14:37
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress This PR is in WIP state label Apr 14, 2026
Copy link
Copy Markdown
Contributor

@MatthewAThompson MatthewAThompson left a comment

Choose a reason for hiding this comment

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

Thanks @daniduong

AI-assisted review:

MUST FIX (Blocking):
Use HTTP status code (409) instead of string matching for error detection

  • More robust and follows HTTP semantics
  • Prevents breakage if message wording changes

Copy link
Copy Markdown
Contributor

@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: 3

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

Inline comments:
In `@packages/automl/frontend/src/app/api/s3.ts`:
- Around line 99-107: The code calls response.json() unconditionally which can
throw on empty/malformed/HTML error bodies and prevent attaching statusCode to
the thrown Error; wrap the JSON parse in a try/catch (or attempt response.text()
fallback) so you safely obtain responseData (or rawBody) even when parsing
fails, then when !response.ok always construct and throw an Error that includes
the descriptive message (using responseData?.error?.message or the raw text) and
attach { statusCode: response.status } to that Error (the existing variable
names response, responseData, and the created error object should be reused so
callers relying on error.statusCode can still detect 409 conflicts).
- Around line 94-97: uploadFileToS3 currently does a direct fetch POST which
bypasses the app's restCREATE()/handleRestFailures() abstraction and omits
explicit credentials and robust error parsing; change uploadFileToS3 to use
restCREATE() (and handleRestFailures()) for consistency if it supports FormData,
otherwise keep fetch but add credentials: 'same-origin', check response.ok
before calling response.json(), and if not ok read text/json conditionally to
attach statusCode to the thrown error; reference uploadFileToS3, restCREATE, and
handleRestFailures when making the change.

In `@packages/autorag/frontend/src/app/api/s3.ts`:
- Around line 99-108: The response.json() call is done before checking
response.ok which can throw and prevent attaching statusCode; change the flow to
first check if (!response.ok) then attempt to parse the body inside a try/catch
(e.g., call response.json() or response.text() as fallback) so you can always
construct an Error with a message and attach { statusCode: response.status }
before throwing; ensure the code paths that currently use responseData,
errorMessage and the thrown error still work when JSON parsing fails by using
fallback text or a default message.
🪄 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: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: c9ff5f3d-fe96-4e1a-adb0-9feb09b969cc

📥 Commits

Reviewing files that changed from the base of the PR and between 1f17fec and bc3b631.

📒 Files selected for processing (4)
  • packages/automl/frontend/src/app/api/s3.ts
  • packages/automl/frontend/src/app/components/configure/AutomlConfigure.tsx
  • packages/autorag/frontend/src/app/api/s3.ts
  • packages/autorag/frontend/src/app/components/configure/AutoragConfigure.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/automl/frontend/src/app/components/configure/AutomlConfigure.tsx

Comment thread packages/automl/frontend/src/app/api/s3.ts Outdated
Comment thread packages/automl/frontend/src/app/api/s3.ts Outdated
Comment thread packages/autorag/frontend/src/app/api/s3.ts Outdated
@daniduong
Copy link
Copy Markdown
Contributor Author

@MatthewAThompson if it's fine with you i think i might just revert to the previous commit where coderabbit wasn't complaining as much 😅, i don't think the string matching is truly blocking tbh, we have that pattern in a couple places already, we can probably address all these later as tech debt

This reverts commit bc3b631.
@MatthewAThompson
Copy link
Copy Markdown
Contributor

@daniduong yeah, I think it's ok to revert back to string matching. We can address later.

@MatthewAThompson
Copy link
Copy Markdown
Contributor

/lgtm

@chrjones-rh
Copy link
Copy Markdown
Contributor

Automated tests are clean:

image

AI-assisted review found no actionable issues.

Manual testing looks good:

image

/lgtm
/approve

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented Apr 17, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: chrjones-rh

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot Bot merged commit e273529 into opendatahub-io:main Apr 17, 2026
57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants