Skip to content

PATCH release/component/project returns 400 Bad Request on duplicate name/version instead of 409 Conflict #4011

@Aman-Cool

Description

@Aman-Cool

Description

Ran into something weird with the PATCH release endpoint. When trying to update a release's version to one that already exists under the same component, the API returns 400 Bad Request instead of 409 Conflict. The backend is actually doing the right thing here; ComponentDatabaseHandler catches the duplicate and returns RequestStatus.DUPLICATE; but that status has no explicit handling in Sw360ReleaseService.updateRelease() so it falls through to the generic catch-all, becomes a plain RuntimeException, and RestExceptionHandler maps it to 400. Same issue on PATCH components and PATCH projects.

How to reproduce

Create two releases under the same component:

POST /api/releases
{"name": "OpenSSL", "version": "1.0.0", "componentId": "<cid>"}

POST /api/releases
{"name": "OpenSSL", "version": "2.0.0", "componentId": "<cid>"}

Then patch the second one to use the same version as the first:

PATCH /api/releases/<second-release-id>
Content-Type: application/json

{"version": "1.0.0"}

What comes back:

HTTP/1.1 400 Bad Request
{"status": 400, "error": "Bad Request", "message": "sw360 release with name 'OpenSSL 1.0.0 cannot be updated."}

What should come back:

HTTP/1.1 409 Conflict

Looking at Sw360ReleaseService.updateRelease() around line 322, there's explicit handling for INVALID_INPUT, NAMINGERROR, DUPLICATE_ATTACHMENT etc. but DUPLICATE is just missing from that list. So it drops into the final else if (requestStatus != SUCCESS && requestStatus != SENT_TO_MODERATOR) block, throws a generic RuntimeException, and RestExceptionHandler.handleRuntimeException() turns that into a 400. The fix is straightforward — just needs an explicit branch for DUPLICATE that throws something mapping to 409. Sw360ComponentService and Sw360ProjectService have the exact same gap.

The annoying part is that ComponentDatabaseHandler is handling this correctly; the duplicate detection works, RequestStatus.DUPLICATE is returned as it should be; the information just gets lost on the way back up through the service layer.

Screenshots (if applicable)

N/A, the steps above reproduce it reliably.

Versions

  • Reproduced on current main, last commit 014c574

SW360 logs

Nothing useful will show up in the logs for this; since the backend returned a status code cleanly rather than throwing, there's no stack trace or error logged anywhere. That's also part of what makes it tricky to diagnose if someone hits it without already knowing where to look.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions