You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When array elements are not nullable, the array validation constraints are applied not to array, but each element
I've modified an existing zod testcase which now fails to visualize this problem:
it('list field non-null', async () => {
const schema = buildSchema(/* GraphQL */ `
input UserCreateInput {
profile: [String!]! @constraint(minLength: 1, maxLength: 5000)
}
directive @constraint(minLength: Int!, maxLength: Int!) on INPUT_FIELD_DEFINITION
`);
const result = await plugin(
schema,
[],
{
schema: 'zod',
directives: {
constraint: {
minLength: ['min', '$1', 'Please input more than $1'],
maxLength: ['max', '$1', 'Please input less than $1'],
},
},
},
{}
);
const wantContains = [
'export function UserCreateInputSchema(): z.ZodObject<Properties<UserCreateInput>>',
'profile: z.array(z.string()).min(1, "Please input more than 1").max(5000, "Please input less than 5000")',
];
for (const wantContain of wantContains) {
expect(result.content).toContain(wantContain);
}
});
@Code-Hex
Thank you for providing such an excellent library — it's been incredibly helpful in my projects.
I've encountered the same issue and created a minimal reproducible example to demonstrate the problem. I hope this will help you investigate it further.
Activity
Code-Hex commentedon Dec 9, 2023
@rwysocki-equinix Could you send me PR for this fix?
ashar-nadeem-lumi commentedon Feb 8, 2024
Bumping this, is there any workaround? Or a way to enforce a min length on the zod array ?
llwire commentedon Nov 15, 2024
Bumping this again.
There is actually no scenario that produces a near-desired outcome.
[String!]! @constraint(min: 5)producesz.array(z.string().min(5))[String]! @constraint(min: 5)producesz.array(z.string().nullable())[String!] @constraint(min: 5)producesz.array(z.string().min(1).max(5)).min(1).max(5).nullish()[String] @constraint(min: 5)producesz.array(z.string().nullable()).min(1).max(5).nullish()The last one might be the closest but making the array entries nullable isn't great when you generate a client-side schema.
Code-Hex commentedon Sep 23, 2025
Could someone please provide the schema definition and the desired output?
hiro1989 commentedon Oct 21, 2025
@Code-Hex
Thank you for providing such an excellent library — it's been incredibly helpful in my projects.
I've encountered the same issue and created a minimal reproducible example to demonstrate the problem. I hope this will help you investigate it further.
Versions
All are the current latest version at 2025-10-21
Summary of Actual vs. Expected Behavior
In short, Array-level
@constraint(minItems, maxItems)is incorrectly applied to element schemas instead of the array schema in generated zod code.Case 1.
[String!]! @constraint(minItems: *, maxItems: *)GraphQL schema:
Generated code:
Case 2.
[String!] @constraint(minItems: *, maxItems: *)GraphQL schema:
Generated code:
Case 3.
[String]! @constraint(minItems: *, maxItems: *)GraphQL schema:
Generated code:
Case 4.
[SkillInput!]! @constraint(minItems: *, maxItems: *)GraphQL schema:
Generated code:
Case 5.
[SkillInput!] @constraint(minItems: *, maxItems: *)GraphQL schema:
Generated code:
Case 6.
[SkillInput]! @constraint(minItems: *, maxItems: *)GraphQL schema:
Generated code:
Thank you in advance for your time and support. I really appreciate all the work you're doing on this project!
vinverdy commentedon Nov 26, 2025
i dont check thoroughly, its not ideal, but have a try with this patch, its zodv4
Code-Hex commentedon Apr 25, 2026
Fixed in #1423. Zod directives are now applied to non-null array fields instead of being skipped because of the non-null wrapper.
Kretiss commentedon Sep 23, 2026
The fix in #1423 covers the Zod generators; valibot still applies list field directives to the items. #1583 ports the same handling to valibot.