Context
Review feedback on #762 (comment) flagged that returning 503 Service Unavailable for service.ErrNoManagedSource is the wrong status code — it's an operator misconfiguration, not a transient backend outage. #762 reverted that change for POST /v1/entries (publishEntry) and DELETE /v1/entries/{type}/{name}/versions/{version} (deletePublishedEntry) back to 500 Internal Server Error, matching the rule in .claude/rules/data-model.md §3.
Two endpoints still return 503 for the same underlying error and are out of step with the rule:
Same reviewer logic applies to both.
Proposal
Pick one consistent status code for ErrNoManagedSource across all entry-claims endpoints (POST /v1/entries, DELETE /v1/entries/.../versions/..., PUT /v1/entries/.../claims, GET /v1/entries/.../claims).
Two reasonable options:
- Standardize on
500 — matches data-model.md §3 today, minimal churn (only the two claims endpoints change). Defensible as "no managed source = server misconfiguration, generic server error."
- Adopt a 4xx that better signals operator error — e.g.
409 Conflict or 412 Precondition Failed. More semantically accurate, but requires updating the rule, all four endpoints, their handler tests, and the Swagger annotations.
Pick one in the issue discussion and update:
internal/api/v1/entries.go (handler bodies + @Failure annotations)
internal/api/v1/entries_test.go (wantStatus cases)
docs/thv-registry-api/{docs.go,swagger.json,swagger.yaml} via task docs
.claude/rules/data-model.md §3 if option 2
Why now
Out of scope for #762 (review only flagged the two endpoints that PR modified) and out of scope for #761 (additive — same status as preceding endpoints). Tracking here so the inconsistency doesn't ship long-term.
Context
Review feedback on #762 (comment) flagged that returning
503 Service Unavailableforservice.ErrNoManagedSourceis the wrong status code — it's an operator misconfiguration, not a transient backend outage. #762 reverted that change forPOST /v1/entries(publishEntry) andDELETE /v1/entries/{type}/{name}/versions/{version}(deletePublishedEntry) back to500 Internal Server Error, matching the rule in.claude/rules/data-model.md§3.Two endpoints still return
503for the same underlying error and are out of step with the rule:PUT /v1/entries/{type}/{name}/claims—updateEntryClaims(predates Default-deny on empty resource claims when authz is active #762)GET /v1/entries/{type}/{name}/claims—getEntryClaims(added by AddGetEntryClaimsadmin endpoint #761)Same reviewer logic applies to both.
Proposal
Pick one consistent status code for
ErrNoManagedSourceacross all entry-claims endpoints (POST /v1/entries,DELETE /v1/entries/.../versions/...,PUT /v1/entries/.../claims,GET /v1/entries/.../claims).Two reasonable options:
500— matchesdata-model.md§3 today, minimal churn (only the twoclaimsendpoints change). Defensible as "no managed source = server misconfiguration, generic server error."409 Conflictor412 Precondition Failed. More semantically accurate, but requires updating the rule, all four endpoints, their handler tests, and the Swagger annotations.Pick one in the issue discussion and update:
internal/api/v1/entries.go(handler bodies +@Failureannotations)internal/api/v1/entries_test.go(wantStatuscases)docs/thv-registry-api/{docs.go,swagger.json,swagger.yaml}viatask docs.claude/rules/data-model.md§3 if option 2Why now
Out of scope for #762 (review only flagged the two endpoints that PR modified) and out of scope for #761 (additive — same status as preceding endpoints). Tracking here so the inconsistency doesn't ship long-term.