Summary
When uploading a skill version that already exists, the server currently returns 400 Bad Request with an error message "Version {version} already exists for skill {name}." This makes it difficult for clients to distinguish between actual validation errors and benign duplicate uploads without parsing the response body.
Proposal
Change the response for "version already exists" from 400 Bad Request to 409 Conflict.
This follows the same pattern as NuGet's server, which returns 409 for duplicate packages. The dotnet nuget push --skip-duplicate flag treats 409 as a non-error, enabling idempotent publish pipelines.
Motivation
We're building a CI/CD pipeline in petabridge-skills that publishes all skills to the server on every push. With 409, the publish script can use HTTP status codes alone to determine behavior:
201 — published successfully
409 — already exists, skip (idempotent no-op)
400 — actual validation error
401/403 — auth problem
Without this, the client has to grep the response body for "already exists" to distinguish duplicates from real errors, which is fragile.
Implementation
One-line change in src/SkillServer/Endpoints.cs — where the existing-version check returns Results.BadRequest(...), change to Results.Conflict(...).
Summary
When uploading a skill version that already exists, the server currently returns 400 Bad Request with an error message
"Version {version} already exists for skill {name}."This makes it difficult for clients to distinguish between actual validation errors and benign duplicate uploads without parsing the response body.Proposal
Change the response for "version already exists" from
400 Bad Requestto409 Conflict.This follows the same pattern as NuGet's server, which returns 409 for duplicate packages. The
dotnet nuget push --skip-duplicateflag treats 409 as a non-error, enabling idempotent publish pipelines.Motivation
We're building a CI/CD pipeline in petabridge-skills that publishes all skills to the server on every push. With 409, the publish script can use HTTP status codes alone to determine behavior:
201— published successfully409— already exists, skip (idempotent no-op)400— actual validation error401/403— auth problemWithout this, the client has to grep the response body for "already exists" to distinguish duplicates from real errors, which is fragile.
Implementation
One-line change in
src/SkillServer/Endpoints.cs— where the existing-version check returnsResults.BadRequest(...), change toResults.Conflict(...).