') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); [DO NOT MERGE] Test all examples against workflow 5.0.0-beta.40 pre-release tarballs by VaguelySerious · Pull Request #51 · vercel/workflow-examples · GitHub
Skip to content

[DO NOT MERGE] Test all examples against workflow 5.0.0-beta.40 pre-release tarballs - #51

Draft
VaguelySerious wants to merge 4 commits into
mainfrom
peter/tarball-prerelease-test
Draft

[DO NOT MERGE] Test all examples against workflow 5.0.0-beta.40 pre-release tarballs#51
VaguelySerious wants to merge 4 commits into
mainfrom
peter/tarball-prerelease-test

Conversation

@VaguelySerious

@VaguelySeriousVaguelySerious commented Aug 11, 2026

Copy link
Copy Markdown
Member

DO NOT MERGE. Throwaway branch for pre-release testing only.

Points every workflow / @workflow/* dependency in all 17 examples at the tarballs from
https://workflow-tarballs-qlvm9j1ne.labs.vercel.dev/ (vercel/workflow @ 6786db9), and refreshes the lockfiles.

This is a 4.3.1 → 5.0.0-beta.40 jump, so the failures below are v5 migration work, not packaging problems.

Build results

pnpm run build per project, on this branch vs. main:

ProjectThis branchmain (4.3.1)
actors, ai-sdk-workflow-patterns, astro, hono, nextjs, nitro, nuxt, rag-agent, sveltekit, tanstack-start, vitepasspass
custom-adapter, kitchen-sinkno build scriptno build script
flight-booking-apppass (after the getWorld() fix below)pass
postgrespass (after the getWorld() fix below)pass
ffmpeg-processingfailpass
birthday-card-generatorfailfail (pre-existing)

flight-booking-app, postgres: getWorld() is async in v5

Type error: Property 'start' does not exist on type 'Promise<World>'.

Expected v5 breaking change. Both examples called getWorld().start?.() in instrumentation.ts. Fixed in
a32dad3 by awaiting first; both build clean after that, and the flight-booking-app preview deploy goes green.
It failed loudly only because these two examples are TypeScript. On 4.x getWorld() returned the World
synchronously, so the old call was correct there. In plain JavaScript on v5 it stays silent: .start is
undefined on the promise, ?.() short-circuits, and the world worker simply never starts.

custom-adapter: the standalone bundle layout changed

"No build script" hid this one. The example builds with the CLI and wires the generated routes into
Bun.serve() by hand, which is exactly the surface v5 reshaped. Four changes, in d199ff2:

  • flow.js / webhook.js are now flow.mjs / webhook.mjs, ESM with named exports only. The existing
    import flow from './...flow.js' resolved to undefined, so flow.POST threw.
  • step.js became __step_registrations.mjs, an internal module that flow.mjs imports. The
    POST /.well-known/workflow/v1/step route is deleted, not repointed: the flow handler serves step
    deliveries now.
  • The SWC plugin's mode: 'client' was removed and merged into mode: 'step'. Passing client to the v5
    plugin fails the transform outright.
  • @swc/core and @workflow/swc-plugin were never declared as dependencies. They resolved through bun's
    flat node_modules; under pnpm they do not, so require.resolve failed. Now declared.

Verified end to end: run starts, all steps execute, webhook link issued.

One false lead worth recording, because it cost time. Before the clean reinstall, require.resolve was picking
up a stale hoisted @workflow/swc-plugin@4.0.1-beta.12 left behind by the failed bun install, shadowing the
tarball's 5.0.0-beta.5-6786db9. The v4 plugin emits import { registerStepFunction } from "workflow/internal/private", a subpath v5 removed, so it looked like the v5 compiler was emitting a dead
import. It is not: with the correct plugin, registrations are inlined as IIFEs and there is no such import.
rm -rf node_modules before drawing conclusions from a directory that bun has touched.

ffmpeg-processing: rollup fails to render a dynamic import in @workflow/core

[nitro] ℹ Building server (builder: rollup, preset: node-server)
node_modules/.../@workflow/core/dist/runtime/quickjs-runtime.js (63:25):
Error when using sourcemap for reporting an error: Can't resolve original location of error.
ERROR replacement content must be a string
at MagicString.update (rollup/dist/es/shared/node-entry.js:977:42)
at ImportExpression.render (rollup/dist/es/shared/node-entry.js:13285:18)
...
at async buildProduction (nitro/dist/_build/rollup.mjs:260:3)

This one looks like an actual SDK/bundler bug rather than a documented breaking change, and it builds fine on 4.3.1.
hono uses nitro build too and passes, so it is not nitro alone. The difference in ffmpeg-processing's
nitro.config.ts is defineNitroConfig from nitro/config plus routes: { "/**": { handler, format: "node" } };
both examples set noExternals: true. The reported line/column in quickjs-runtime.js is unreliable (the
sourcemap lookup itself fails), but the rollup frame is ImportExpression.render, so the trigger is a dynamic
import() in the compiled quickjs runtime.

birthday-card-generator: not a regression

Fails identically on main with Error: Missing API key. Pass it to the constructor new Resend("re_123").
It needs RESEND_API_KEY at build time.

Notes on the packaging itself

  • Bun cannot install these tarballs. The tarballs declare their siblings by URL
    (@workflow/core: https://.../workflow-core.tgz), and bun 1.3.4 fails on transitive URL deps with
    error: @workflow/errors@https://... failed to resolve. Reproducible in a clean directory with only
    workflow.tgz as a dependency. So actors, custom-adapter, and postgres (bun-first in their READMEs)
    have stale bun.lock files on this branch. postgres had no pnpm lockfile at all, so one was added to make
    it installable.
  • Installing needs pnpm install --config.min-release-age=0. @workflow/core pins
    @aws-sdk/credential-provider-web-identity@3.972.49, whose @smithy/core@3.32.0 requires
    @smithy/types@^4.17.0, published 2026-08-10. Any non-zero min-release-age hides it and resolution fails
    with ERR_PNPM_NO_MATCHING_VERSION.
  • The committed lockfiles cannot be installed from. pnpm writes URL-tarball entries with no integrity
    field, and pnpm 10.34.5 then refuses to install them: ERR_PNPM_MISSING_TARBALL_INTEGRITY. Not one of the 17
    lockfiles here carries integrity for its tarball entries. A fresh checkout needs both pnpm-lock.yaml and
    node_modules removed before pnpm install will proceed. Deleting only one of the two is not enough. Vercel's
    builds are unaffected, since they install without a usable lockfile anyway.
  • Example source was modified only where v5 required it: instrumentation.ts in flight-booking-app and
    postgres, and server.ts + workflow-plugin.ts in custom-adapter.

Temporary: swaps every `workflow` / `@workflow/*` dep in all 17 examples
from the published 4.x versions to the tarballs served by the
workflow-tarballs deployment for vercel/workflow @ 6786db9, and refreshes
the lockfiles. Adds a pnpm lockfile for `postgres`, which only had a
bun.lock (bun cannot resolve the tarballs' nested URL deps).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercelBot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
birthday-card-generatorReadyReadyPreviewAug 11, 2026 7:26pm
flight-booking-appReadyReadyPreviewAug 11, 2026 7:26pm

`getWorld()` returns a Promise<World> as of v5, so `getWorld().start?.()`
no longer type-checks (and silently no-ops at runtime).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The example has no build script, so the earlier sweep never exercised it.
Running it surfaced four v5 changes:
- `flow.js` / `webhook.js` are now `flow.mjs` / `webhook.mjs`, ESM with
named exports only, so the default imports resolved to undefined.
- `step.js` became `__step_registrations.mjs`, an internal module that
`flow.mjs` imports. The `POST /.well-known/workflow/v1/step` route is
deleted rather than repointed.
- The SWC plugin's `client` mode was removed and merged into `step`.
- `@swc/core` and `@workflow/swc-plugin` were never declared. They
resolved through bun's flat node_modules; under pnpm they do not.
Verified end to end: the run starts, all steps execute, and the webhook
link is issued.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The nitro build failed with "replacement content must be a string" from
rollup's ImportExpression.render. It is a rollup 4.53.3 bug, reproducible
only when @vercel/oidc 3.0.5 and 3.8.2 are both in the tree: rollup
renders the dynamic imports in oidc 3.0.5's get-vercel-oidc-token.js while
their target modules are assigned to no chunk, so a Module object reaches
MagicString.overwrite instead of a string.
The stale lockfile was holding rollup at 4.53.3 and @vercel/sandbox at
1.0.4 (whose ^3.0.5 oidc range was pinned to literally 3.0.5). Raising the
rollup floor to ^4.62.4 encodes the actual constraint; the regenerated
lockfile also floats sandbox to 1.10.2, which drops the 3.0.5 copy.
The lockfile was regenerated against a scratch pnpm store so its tarball
entries carry integrity hashes, which makes it installable again.
No Workflow SDK change is involved: the example needs no source changes
for v5, and relaxing world-vercel's @vercel/oidc pin does not fix it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

DiffPackageSupply Chain
Security
VulnerabilityQualityMaintenanceLicense
Added@​types/​multer@​2.2.01001007387100
Added@​types/​node@​20.19.431001008196100
Added@​vercel/​sandbox@​1.10.28110010099100
Addedcors@​2.8.610010010084100
Addedmulter@​2.2.010010010092100
Addedrollup@​4.62.49610010098100

View full report

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@VaguelySerious