Bug
@workflow/world-local/dist/queue.js imports zod (v3 compat) and creates a z.object() containing schemas from @workflow/world/dist/queue.js, which imports from zod/v4 (native). When Zod v3's ZodObject._parse() iterates the shape, it calls ._parse() on the v4-native schemas — which don't have that method.
TypeError: keyValidator._parse is not a function
Root cause
@workflow/world/dist/queue.js (line 1):
import { z } from 'zod/v4'; // native v4
Creates ValidQueueName, MessageId etc. as v4-native schemas.
@workflow/world-local/dist/queue.js (line 7):
import z from 'zod'; // v3 compat layer
Then mixes them:
const HeaderParser = z.object({
'x-vqs-queue-name': ValidQueueName, // v4 native — no ._parse()
'x-vqs-message-id': MessageId, // v4 native — no ._parse()
'x-vqs-message-attempt': z.coerce.number(), // v3 compat
});
When HeaderParser.safeParse() runs, v3's internal ZodObject._parse() calls shape[key]._parse() on each value. The v4-native schemas don't have ._parse() → crash.
Reproduction
- Use
zod@^3.25 (v4 published under v3 semver, with v3 compat layer)
- Use
workflow@4.2.0-beta.75
- Trigger any workflow →
POST /.well-known/workflow/v1/flow returns 500
Affected versions
@workflow/world@4.1.0-beta.15
@workflow/world-local@4.1.0-beta.48
- Also present in older versions (
4.0.1-beta.x)
Workaround
Patch @workflow/world-local/dist/queue.js to use import { z } from 'zod/v4' instead of import z from 'zod'.
Suggested fix
Either consistently use zod/v4 in both packages, or consistently use zod (v3 compat). Since @workflow/world/dist/queue.js uses z.templateLiteral() (v4-only API), the fix should be to change @workflow/world-local to also import from zod/v4.
Related
This is the same crash as #686 but with the actual root cause identified. That issue was closed with "upgrade to Zod 4" which only masks the bug.
Bug
@workflow/world-local/dist/queue.jsimportszod(v3 compat) and creates az.object()containing schemas from@workflow/world/dist/queue.js, which imports fromzod/v4(native). When Zod v3'sZodObject._parse()iterates the shape, it calls._parse()on the v4-native schemas — which don't have that method.Root cause
@workflow/world/dist/queue.js(line 1):Creates
ValidQueueName,MessageIdetc. as v4-native schemas.@workflow/world-local/dist/queue.js(line 7):Then mixes them:
When
HeaderParser.safeParse()runs, v3's internalZodObject._parse()callsshape[key]._parse()on each value. The v4-native schemas don't have._parse()→ crash.Reproduction
zod@^3.25(v4 published under v3 semver, with v3 compat layer)workflow@4.2.0-beta.75POST /.well-known/workflow/v1/flowreturns 500Affected versions
@workflow/world@4.1.0-beta.15@workflow/world-local@4.1.0-beta.484.0.1-beta.x)Workaround
Patch
@workflow/world-local/dist/queue.jsto useimport { z } from 'zod/v4'instead ofimport z from 'zod'.Suggested fix
Either consistently use
zod/v4in both packages, or consistently usezod(v3 compat). Since@workflow/world/dist/queue.jsusesz.templateLiteral()(v4-only API), the fix should be to change@workflow/world-localto also import fromzod/v4.Related
This is the same crash as #686 but with the actual root cause identified. That issue was closed with "upgrade to Zod 4" which only masks the bug.