Skip to main content
← Back to list
01Issue
BugIn ProgressSwamp CLIPublic
Assigneeszack

Relationships

#3873 workflow validate derives required arguments from zod's JSON Schema, so zod 4.6.7 rejects workflows that omit optional preprocess and catch arguments

Opened by zack · 10/23/2026

Description

swamp workflow validate decides which method arguments a step must supply from the required list of zod's JSON Schema (z.toJSONSchema(method.arguments, { io: "input" })). The only adjustment swamp makes is to drop fields whose property carries a default (stripDefaultsFromRequired in src/libswamp/types/schema_helpers.ts). The list is used in src/libswamp/workflows/validate.ts (both the definition path and resolveByType).

That list is not the same as "the arguments fail to parse without this field". It changes with the zod version, and zod 4.5+ (shipped by #3335, zod 4.6.7) changes it:

  • z.preprocess(fn, X) fields are now listed as required under io: "input", even when fn turns a missing value into a valid one. 4.4.3 did not list them.
  • .catch() wrapped around a transform is now listed as required and loses its default, so swamp's default-stripping no longer removes it.
  • Intersections (a.and(b)) are merged into one object, so their required now reaches the top level. Under 4.4.3 they emitted allOf with no top-level required, and validate checked nothing for them.

The first two make validate reject workflows that run fine today. The third goes the other way: validate was under-reporting required arguments before.

Impact (registry scan, 4.4.3 vs 4.6.7)

All 1,209 third-party registry extensions and all first-party swamp-extensions behaviors were loaded under both zod versions and their schemas compared:

  • 1 real regression: @hivemq/asdlc, method validate. noChange, planClaim, prUrl, ticketTitle and ticketDescription are each a z.preprocess that turns a missing value into false or an empty string. Under 4.4.3 the arguments parse without them. Under 4.6.7 validate requires all five, so workflows that omit them would fail swamp workflow validate.
  • 15 third-party extensions plus first-party typesafe-ai (ask.questions, choice.criteria, score.criteria) newly report arguments that were already required at runtime (their parse fails or throws without them). Only the timing of the error changes.

Steps to Reproduce

  1. A behavior whose method arguments include flag: z.preprocess((v) => v === true || v === "true", z.boolean()).
  2. A workflow step that calls the method without flag.
  3. On zod 4.4.3 (stable today), swamp workflow validate passes and the run works: flag parses to false.
  4. On zod 4.6.7 (main after #3335), swamp workflow validate reports flag as a missing required argument. The method still parses without it.

Expected

The required-argument check reflects what the arguments actually accept, whatever the zod version. A field is required only when the arguments fail to parse without it.

Suggested fix

Derive required arguments from zod rather than from JSON Schema required. For example:

  • treat a top-level field as required only if parsing the arguments with that field absent produces an issue at that path, or
  • read each field's own optionality from zod (_zod.optin), and treat preprocess/catch fields by whether they accept undefined.

That fixes the preprocess and .catch() cases and keeps the (correct) intersection case. Ideally it also covers global arguments and the swamp-club#3681 transform handling, so the rule no longer depends on how a given zod version renders JSON Schema.

This should land before or with the zod 4.6.7 bump reaching stable. The release from #3335 has not been promoted: its UAT run was cancelled and revert #3336 is on hold.

Environment

  • swamp main at 058c32be2 (zod 4.6.7) vs stable 20261023.183232.0-sha.c0e1560b (zod 4.4.3)
  • Linux x86_64
02Bog Flow
✓OPEN✓TRIAGED◉IN PROGRESS○SHIPPED+ 1 MOREASSIGNED+ 5 MOREREVIEW+ 9 MOREVERIFICATION_STARTED

In Progress

10/23/2026, 9:53:18 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
zack assigned zack10/23/2026, 9:43:26 PM

Sign in to post a ripple.