fix(world-local): skip Nov 2025 ghost versions on npm#2168
Conversation
`@workflow/world-local` versions 5.0.0-beta.8, beta.9, and beta.10 are published on npm from an abandoned November 2025 release train (see "About this version" timestamps on npmjs.com). They use the old `createEmbeddedWorld` export and 4.x dependencies, while current code uses `createLocalWorld` and 5.x deps. The last "Version Packages (beta)" PR (#2147) bumped world-local's package.json from beta.7 → beta.8. The actual publish to npm was either silently skipped or 409'd, so the npm slot still holds the November content while `@workflow/core@5.0.0-beta.9` was published with a hard dependency pin on `@workflow/world-local@5.0.0-beta.8` — pointing downstream consumers (e.g. Ash) at incompatible code: npm ERR! MISSING_EXPORT: "createLocalWorld" is not exported by ".../@workflow/world-local@5.0.0-beta.8/.../dist/index.js" Bump packages/world-local/package.json to 5.0.0-beta.10 (the highest contaminated slot) so the next Version Packages PR computes 5.0.0-beta.11, which is a free slot on npm. That cascades a patch bump to core (workspace:*) → core@5.0.0-beta.10 with a clean pin to world-local@5.0.0-beta.11. No functional code changes.
🦋 Changeset detectedLatest commit: 3d83f2a The changes in this PR will be included in the next version bump. This PR includes changesets to release 18 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 |
📊 Benchmark Results
workflow with no steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro workflow with 1 step💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro workflow with 10 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro workflow with 25 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro workflow with 50 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro Promise.all with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro Promise.all with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro Promise.all with 50 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro Promise.race with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro Promise.race with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro Promise.race with 50 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro workflow with 10 sequential data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro workflow with 25 sequential data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro workflow with 50 sequential data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro workflow with 10 concurrent data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro workflow with 25 concurrent data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro workflow with 50 concurrent data payload steps (10KB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro Stream Benchmarks (includes TTFB metrics)workflow with stream💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro stream pipeline with 5 transform steps (1MB)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro 10 parallel streams (1MB each)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro fan-out fan-in 10 streams (1MB each)💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro SummaryFastest Framework by WorldWinner determined by most benchmark wins
Fastest World by FrameworkWinner determined by most benchmark wins
Column Definitions
Worlds:
❌ Some benchmark jobs failed:
Check the workflow run for details. |
🧪 E2E Test Results❌ Some tests failed Summary
❌ Failed Tests▲ Vercel Production (2 failed)fastify (1 failed):
hono (1 failed):
💻 Local Development (1 failed)hono-stable (1 failed):
📋 Other (2 failed)e2e-local-prod-nest-stable (1 failed):
e2e-local-prod-tanstack-start- (1 failed):
Details by Category❌ ▲ Vercel Production
❌ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
❌ 📋 Other
❌ Some E2E test jobs failed:
Check the workflow run for details. |
Signed-off-by: Nathan Rajlich <n@n8.io>
Why
`@workflow/world-local@5.0.0-beta.9` (latest published, May 29 2026) is broken: it imports `createLocalWorld` from `@workflow/world-local`, but `@workflow/world-local@5.0.0-beta.8` (the pinned version) is a November 2025 ghost that exports the old `createEmbeddedWorld` name and uses 4.x dependencies.
Downstream consumers (e.g. Ash) hit:
```
[MISSING_EXPORT] "createLocalWorld" is not exported by ".../@workflow/world-local@5.0.0-beta.8/.../dist/index.js"
[MISSING_EXPORT] "WorkflowAPIError" is not exported by ".../@workflow/errors@5.0.0-beta.5/.../dist/index.js"
```
(The `WorkflowAPIError` failure is a downstream symptom: `world-local@beta.8` pins `@workflow/errors@5.0.0-beta.4`, which predates `WorkflowAPIError`.)
Root cause: npm version-slot contamination
`@workflow/world-local` has two non-overlapping release trains sharing the `5.0.0-beta.N` namespace:
PR #2147 (last night's Version Packages) bumped `packages/world-local/package.json` from `beta.7` → `beta.8`. The actual publish to npm either silently failed or 409'd because the slot was occupied — but `@workflow/core` had already been published as `beta.9` with the new pin baked in via `workspace:*` rewriting:
```json
// @workflow/core@5.0.0-beta.9 package.json
"@workflow/world-local": "5.0.0-beta.8" // ← ghost
```
So every consumer of `core@beta.9` resolves to the November `world-local`.
Evidence
Fix
Bump `packages/world-local/package.json` from `5.0.0-beta.8` → `5.0.0-beta.10` (the highest contaminated slot). The next "Version Packages (beta)" PR (#2162) will compute the next pre-release after `beta.10` = `5.0.0-beta.11`, which is free on npm.
That cascade-bumps consumers via `updateInternalDependencies: patch` + `workspace:*` rewriting:
The intermediate workspace marker `beta.10` is never published — `changeset publish` queries npm and skips occupied slots, and only `beta.11` (computed by the Version Packages PR) is in `package.json` by the time `pnpm ci:publish` runs.
Validation
Why not `unpublish` the ghosts?
npm publishes are immutable; unpublish has a 72-hour window only, and the ghost versions are 6 months old. Skipping past them is the only path forward.
Follow-up
Once this lands, downstream Ash work blocked on PR #2157 (step-side `experimental_setAttributes`) can resume by bumping to the cascaded `@workflow/core@5.0.0-beta.10`.