fix(runtime): carry spec-validation issues + 422 through metadata save/publish errors#2589
Merged
Merged
Conversation
…ata save/publish errors
protocol.saveMetaItem throws a field-anchored spec-validation error (status 422,
code invalid_metadata, issues:[{path,message,code}]), but the HTTP dispatcher
collapsed it to a single message (save even hardcoded 400) and publish dropped
issues from each failed[] entry. The Studio could therefore only show a generic
banner, never point at the offending field.
- Add errorFromThrown(e, fallback) dispatcher helper: preserves the error's own
status (validation now surfaces as 422, not a downgraded 400) and attaches
{code, issues} under error.details when present; unchanged for plain errors.
Wired into the meta save (PUT /meta/:type/:name) and publish
(POST /packages/:id/publish-drafts) catch sites.
- publishPackageDrafts carries issues into each failed[] entry.
Server half of "surface validation at the save/publish moment, on the field".
Additive to the error payload; only behavior change is the more-correct 422.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 16 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why (UX eval #4 — validation up-front + inline errors)
When a Studio user saves an invalid metadata draft,
protocol.saveMetaItemalready validates it against its spec Zod schema and throws a rich, field-anchored error:…but the HTTP dispatcher threw all of that away:
http-dispatcher.tsPUT catch) didthis.error(e.message, 400)— hardcoded 400,issuesdropped;publishPackageDraftsper-draft catch) flattened each failure to{ type, name, error }—issuesdropped.So the Studio could only show a generic "failed validation" banner / toast, never point at the offending field. This is the server half of making validation errors land on the field, at the save/publish moment (the #1 "silent failure" UX theme).
What
errorFromThrown(e, fallbackStatus)dispatcher helper — preserves the error's ownstatus(validation now surfaces as 422, not a downgraded 400) and attaches{ code, issues }undererror.detailswhen present. Errors carrying neither behave exactly as before. Wired into the metadata save and publish catch sites.publishPackageDraftsnow carriesissuesinto eachfailed[]entry.Resulting error body on a failed save:
{ "success": false, "error": { "message": "[invalid_metadata] object/bad failed spec validation: fields.amount.type: Required", "code": 422, "details": { "code": "invalid_metadata", "issues": [{ "path": "fields.amount.type", "message": "Required", "code": "invalid_type" }] } } }Compatibility
Purely additive to the error payload (
error.details.issues). The only behavior change is the more-correct 422 (was 400) for a failed metadata save — 422 is already the validation status the protocol raises and is used elsewhere. Plain errors (nostatus/issues) are unchanged; the existing "should return error if save fails" test still asserts 400.Tests
New dispatcher test: a
saveMetaItemthat throws a422 / invalid_metadata / issues[...]error yields a 422 response witherror.details.issuespreserved (path intact). Full@objectstack/runtime(448) +@objectstack/metadata-protocol(8) suites green; both packages build (incl. DTS).The objectui half (extract
error.details.issues→ show field-anchored in the Studio) follows in a companion objectui PR; verified end-to-end there.🤖 Generated with Claude Code