Relationships
#2783 Object-level refinements on globalArguments schemas are not enforced at execution time
Opened by stack72 · 9/30/2026· Shipped 9/30/2026
Description
Follow-up to swamp-club#2766 (PR swamp/#2737). A globalArguments schema that uses .refine() or .superRefine() on the object is now checked field by field during the lenient global-argument check (parseGlobalArgumentsLeniently in src/domain/models/zod_type_coercion.ts), because zod 4 refuses .partial() on refined objects. The field checks and defaults apply, but object-level refinements never run, even when every global argument is resolved.
Before #2737 these schemas crashed on every fully resolved run (fail closed). Now they run with the refinement unchecked (fail open). For a cross-field invariant such as at least one of apiKey or token must be set, a definition with neither now reaches the method.
Steps to reproduce
Model with:
const G = z.object({ apiKey: z.string().optional(), token: z.string().optional() })
.superRefine((v, ctx) => { if (!v.apiKey && !v.token) ctx.addIssue({ code: 'custom', message: 'apiKey or token required' }); });Definition with globalArguments: {} and run any method.
- Expected: Global arguments validation failed: apiKey or token required
- Actual: the method runs with neither credential.
Suggested direction
When no global argument is unresolved, after the per-field pass also run the full schema over the parsed data and report its object-level (root-path) issues, while still ignoring missing-required-field issues so the lenient contract for ephemeral direct-execution instances holds. Needs a check of how zod 4 orders object refinements against missing-key issues (refinements may be skipped when the object already has issues). Applies to method execution, swamp model validate and direct type execution, which all share the helper.
Raised as a medium finding by the CI adversarial review on PR #2737.
Shipped
Click a lifecycle step above to view its details.
Sign in to post a ripple.