PUT /api/admin/objects/{id}/fields returns a bare 422 on UnknownField / TypeMismatch / Unresolved (the admin handler maps all three FieldError variants to StatusCode::UNPROCESSABLE_ENTITY with no body — crates/api/src/admin_objects.rs). The db layer's FieldError actually carries the offending field key + reason, but that detail is dropped at the HTTP boundary.
Consequence for the frontend (object authoring, milestone 2): when a field write is rejected, the form can only show a generic form-level "the server rejected the changes" banner (form.rejected) — it cannot highlight which flexible field was wrong. Client-side validation catches required/empty cases, but type/reference mismatches that only the server knows about surface as an opaque 422.
This also affects the publish gate's MissingRequiredFields (issue #16 closed) and any other admin validation 422 — they're all bare today.
What to do
Return a structured 422 body from set_fields (and consider the other admin validation 422s) carrying the field key(s) + error kind, e.g. { "errors": [{ "field": "material", "kind": "unresolved" }] }. Add the schema to OpenAPI so it's typed on the client.
Frontend: map the structured errors onto the specific FieldInputs (per-field error messages) instead of the generic banner.
References
crates/api/src/admin_objects.rs — set_fields handler (the FieldError → 422 mapping)
web/src/objects/object-form.tsx / object-new-page.tsx / object-edit-form.tsx (currently show form.rejected)
Noted in the M2 design follow-ups.
## Context
`PUT /api/admin/objects/{id}/fields` returns a **bare 422** on `UnknownField` / `TypeMismatch` / `Unresolved` (the admin handler maps all three `FieldError` variants to `StatusCode::UNPROCESSABLE_ENTITY` with no body — `crates/api/src/admin_objects.rs`). The `db` layer's `FieldError` actually carries the offending field key + reason, but that detail is dropped at the HTTP boundary.
Consequence for the frontend (object authoring, milestone 2): when a field write is rejected, the form can only show a generic form-level "the server rejected the changes" banner (`form.rejected`) — it cannot highlight *which* flexible field was wrong. Client-side validation catches required/empty cases, but type/reference mismatches that only the server knows about surface as an opaque 422.
This also affects the publish gate's `MissingRequiredFields` (issue #16 closed) and any other admin validation 422 — they're all bare today.
## What to do
- Return a structured 422 body from `set_fields` (and consider the other admin validation 422s) carrying the field key(s) + error kind, e.g. `{ "errors": [{ "field": "material", "kind": "unresolved" }] }`. Add the schema to OpenAPI so it's typed on the client.
- Frontend: map the structured errors onto the specific `FieldInput`s (per-field error messages) instead of the generic banner.
## References
- `crates/api/src/admin_objects.rs` — `set_fields` handler (the `FieldError` → 422 mapping)
- `crates/db/src/catalog.rs` — `FieldError { UnknownField(String), TypeMismatch{field,expected}, Unresolved{field,kind}, .. }` (already carries detail)
- `web/src/objects/object-form.tsx` / `object-new-page.tsx` / `object-edit-form.tsx` (currently show `form.rejected`)
- Noted in the M2 design follow-ups.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Context
PUT /api/admin/objects/{id}/fieldsreturns a bare 422 onUnknownField/TypeMismatch/Unresolved(the admin handler maps all threeFieldErrorvariants toStatusCode::UNPROCESSABLE_ENTITYwith no body —crates/api/src/admin_objects.rs). Thedblayer'sFieldErroractually carries the offending field key + reason, but that detail is dropped at the HTTP boundary.Consequence for the frontend (object authoring, milestone 2): when a field write is rejected, the form can only show a generic form-level "the server rejected the changes" banner (
form.rejected) — it cannot highlight which flexible field was wrong. Client-side validation catches required/empty cases, but type/reference mismatches that only the server knows about surface as an opaque 422.This also affects the publish gate's
MissingRequiredFields(issue #16 closed) and any other admin validation 422 — they're all bare today.What to do
set_fields(and consider the other admin validation 422s) carrying the field key(s) + error kind, e.g.{ "errors": [{ "field": "material", "kind": "unresolved" }] }. Add the schema to OpenAPI so it's typed on the client.FieldInputs (per-field error messages) instead of the generic banner.References
crates/api/src/admin_objects.rs—set_fieldshandler (theFieldError→ 422 mapping)crates/db/src/catalog.rs—FieldError { UnknownField(String), TypeMismatch{field,expected}, Unresolved{field,kind}, .. }(already carries detail)web/src/objects/object-form.tsx/object-new-page.tsx/object-edit-form.tsx(currently showform.rejected)