Describe the bug and the expected behavior
Since zod 4.6.0, getConstraints() (@conform-to/zod/v4/future) and getZodConstraint() (@conform-to/zod/v4) silently drop every constraint derived from checks: minLength, maxLength, pattern (from .regex()), min, max and accept. Only required, multiple and the enum pattern survive.
Root cause: v4/constraint.ts reads the check metadata from the schema's _zod.bag (bag.minimum, bag.maximum, bag.patterns, bag.mime). Zod 4.6 stopped writing that metadata onto the bag at construction time – checks are now folded lazily (aggregateChecks() in core/json-schema-processors), and the Zod Classic accessors .minLength / .maxLength / .minValue / .maxValue / .format became getters that are computed on first read (see "members materialize on first read" in the Zod 4.6 release notes, zod PR #6554). So on 4.6 schema._zod.bag is {} for a plain z.string().min(2) even though schema.minLength === 2.
Expected: the same constraints as on zod ≤ 4.5. Possible fix: read the Classic getters (schema.minLength, schema.maxLength, schema.minValue, schema.maxValue, …) where available, or fold def.checks ($ZodCheckMinLength, $ZodCheckMaxLength, $ZodCheckGreaterThan, $ZodCheckLessThan, $ZodCheckRegex, $ZodCheckMimeType, …) directly instead of relying on the bag, which zod treats as internal.
Affects @conform-to/zod 1.20.x and 1.21.1 (peer range ^3.21.0 || ^4.0.0 includes 4.6).
Conform version
@conform-to/zod 1.21.1 (also 1.20.1), zod 4.6.0 – 4.6.4 (works on 4.5.4)
Steps to Reproduce the Bug or Issue
import { getConstraints } from "@conform-to/zod/v4/future";
import { z } from "zod";
const schema = z.object({
name: z.string().min(2).max(50).regex(/^[a-z]+$/),
age: z.number().min(18).max(99),
avatar: z.file().mime(["image/png"]),
});
console.log(JSON.stringify(getConstraints(schema)));
console.log(JSON.stringify(schema.shape.name._zod.bag), schema.shape.name.minLength);
zod 4.5.4:
{"name":{"required":true,"minLength":2,"maxLength":50,"pattern":"^(?=.*(?:^[a-z]+$)).*$"},"age":{"required":true,"min":18,"max":99},"avatar":{"required":true,"accept":"image/png"}}
{"minimum":2,"maximum":50,"format":"regex","patterns":{}} 2
zod 4.6.4:
{"name":{"required":true},"age":{"required":true},"avatar":{"required":true}}
{} 2
What browsers are you seeing the problem on?
No response (Node 24, runtime-independent)
Screenshots or Videos
No response
Additional context
Parsing/coercion (coerceFormValue, formatResult, parseWithZod) is unaffected; only the constraint extraction for the HTML attributes regresses.
Describe the bug and the expected behavior
Since zod 4.6.0,
getConstraints()(@conform-to/zod/v4/future) andgetZodConstraint()(@conform-to/zod/v4) silently drop every constraint derived from checks:minLength,maxLength,pattern(from.regex()),min,maxandaccept. Onlyrequired,multipleand the enumpatternsurvive.Root cause:
v4/constraint.tsreads the check metadata from the schema's_zod.bag(bag.minimum,bag.maximum,bag.patterns,bag.mime). Zod 4.6 stopped writing that metadata onto the bag at construction time – checks are now folded lazily (aggregateChecks()incore/json-schema-processors), and the Zod Classic accessors.minLength/.maxLength/.minValue/.maxValue/.formatbecame getters that are computed on first read (see "members materialize on first read" in the Zod 4.6 release notes, zod PR #6554). So on 4.6schema._zod.bagis{}for a plainz.string().min(2)even thoughschema.minLength === 2.Expected: the same constraints as on zod ≤ 4.5. Possible fix: read the Classic getters (
schema.minLength,schema.maxLength,schema.minValue,schema.maxValue, …) where available, or folddef.checks($ZodCheckMinLength,$ZodCheckMaxLength,$ZodCheckGreaterThan,$ZodCheckLessThan,$ZodCheckRegex,$ZodCheckMimeType, …) directly instead of relying on the bag, which zod treats as internal.Affects
@conform-to/zod1.20.x and 1.21.1 (peer range^3.21.0 || ^4.0.0includes 4.6).Conform version
@conform-to/zod 1.21.1 (also 1.20.1), zod 4.6.0 – 4.6.4 (works on 4.5.4)
Steps to Reproduce the Bug or Issue
zod 4.5.4:
zod 4.6.4:
What browsers are you seeing the problem on?
No response (Node 24, runtime-independent)
Screenshots or Videos
No response
Additional context
Parsing/coercion (
coerceFormValue,formatResult,parseWithZod) is unaffected; only the constraint extraction for the HTML attributes regresses.