Backport #2055 to stable: [world-vercel] v4 event wire format (with structured-error compat)#2414
Backport #2055 to stable: [world-vercel] v4 event wire format (with structured-error compat)#2414github-actions[bot] wants to merge 3 commits into
Conversation
Signed-off-by: Peter Wielander <mittgfu@gmail.com>
🦋 Changeset detectedLatest commit: 0d95c2e The changes in this PR will be included in the next version bump. This PR includes changesets to release 20 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The v4 wire format assumes the runtime hands `events.create` a dehydrated
`Uint8Array` for every payload field. On this line run/step errors are NOT
dehydrated — the runtime emits them as a plain string (step_failed /
step_retrying) or a `{ message, stack }` object (run_failed). The split's
Uint8Array guard therefore threw on every failure event.
Route a non-Uint8Array `error` field (plus the sibling `stack`) into the
frame meta instead, so the backend rebuilds the same StructuredError the
pre-v4 wire produced. On read, the backend returns that StructuredError as
the ref's CBOR bytes in the frame body, so decode the structured-error
event types back into `eventData.error` — the core step-event reducer
reads `.message` / `.stack` off it directly and has no hydrate step for
errors on this line.
Also drops the native-run-attributes and webhook/system-hook meta fields
from the wire allowlist: those eventData fields do not exist on this
line's @workflow/world schema, and the schema-derived exhaustiveness guard
flags them as stale. Requires the matching backend change to parse
`error` / `stack` from the v4 frame meta.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🧪 E2E Test Results❌ Some tests failed Summary
❌ Failed Tests▲ Vercel Production (110 failed)astro (10 failed):
example (10 failed):
express (10 failed):
fastify (10 failed):
hono (10 failed):
nextjs-turbopack (10 failed):
nextjs-webpack (10 failed):
nitro (10 failed):
nuxt (10 failed):
sveltekit (10 failed):
vite (10 failed):
🌍 Community Worlds (95 failed)redis (17 failed):
turso (78 failed):
Details by Category❌ ▲ Vercel Production
✅ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
✅ 🪟 Windows
❌ 🌍 Community Worlds
✅ 📋 Other
❌ Some E2E test jobs failed:
Check the workflow run for details. |
|
(AI) Updated this backport to actually work on The auto-backport was a clean git merge, but #2055's v4 wire format has a hard dependency on a runtime refactor that landed on newer lines but is not on
As-is, the v4 split's This update carries stable's structured errors in the frame meta and decodes them back on read — no breaking change, no |
The runtime emits `isWebhook` on hook_created (the suspension handler) and the backend reads it to mark webhook hooks, which must not be resumable via the public webhook endpoint. The schema-derived wire-allowlist guard had flagged `isWebhook` as stale because this line's @workflow/world HookCreatedEventSchema did not declare it — so it was dropped, breaking webhook hooks on the v4 wire. Declare `isWebhook` on HookCreatedEventSchema (matching the field the runtime already sends and the backend already consumes) and route it through the v4 frame meta. Unlike isWebhook, isSystem / native run attributes / attr_set are genuinely absent from this line's runtime and schema, so they stay off the wire. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Backport of #2055 to
stable. The v4 wire format moves event metadata and the user payload into a single length-prefixed binary frame, eliminating the per-event ref-resolution round-trip on event listings.Unlike the clean cherry-pick the backport bot assumed, #2055's wire format was co-designed with a runtime change that only exists on newer lines (there, the runtime serializes run/step errors into opaque bytes before
events.create). On this line errors are still plain values, so this PR adapts the adapter — plus one small, additive@workflow/worldschema fix — to carry them correctly. No breaking change:WorkflowRun.error/Step.errorkeep theirStructuredErrorshape.What this does
[u32_be meta_len][cbor meta][u32_be body_len][bytes]. Metadata rides in the CBOR meta; the user payload is the opaque body./refsround-trip.EventResult/Event/PaginatedResponse<Event>shapes the runtime consumes are unchanged.Stable-specific adaptations (vs. #2055)
step_failed/step_retrying) or a{ message, stack }object (run_failed), not dehydrated bytes. They are carried in the frame meta and decoded back on read, so the Vercel backend (world-vercel) materializes the sameStructuredErrorthe previous wire produced — the replay reducer reads.message/.stackdirectly and there is no hydrate step for errors on this line. Depends on the matchingworld-vercelbackend change (parseerror/stackfrom the v4 frame meta) being deployed first; until then the error-path E2E lanes report "Unknown error".hook_created.isWebhookis kept on the wire and declared onHookCreatedEventSchema— the runtime emits it and the backend consumes it to reject public-webhook-endpoint resumption.attr_set/isSystem). A schema-derived exhaustiveness guard keeps the wire allowlist in sync with the event schema in both directions.Test plan
hook_created.isWebhookroutingworld-vercelbackend change is deployed, then re-run🤖 Generated with Claude Code