Skip to content

Conversation

@mohankumarelec
Copy link

This pull request enhances ZodTuple by adding .min(), .max(), .length(), and .nonempty() methods, similar to those available on ZodArray.

Currently, when a z.tuple() schema is converted to a JSON Schema, it lacks minItems and maxItems properties. This results in an inaccurate schema that could, for example, incorrectly validate an empty array.

By adding these length-based validation methods, the JSON Schema conversion now correctly includes the tuple's length constraints, ensuring more precise and reliable validation.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 30, 2025

Walkthrough

This change adds length-based constraints to the ZodTuple schema by introducing four new chainable methods: min(), nonempty(), max(), and length(). These methods enable constraining tuple lengths following patterns consistent with existing array/tuple validation. Each method wires internally to corresponding checks (minLength, maxLength, or length). The implementation preserves the existing rest signature and doesn't modify existing behavior, maintaining backward compatibility.

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title "feat: Add length constraints to ZodTuple for JSON Schema" directly summarizes the main change in the PR—adding length-based validation methods to ZodTuple. It's specific and clear about what's being modified (ZodTuple), what feature is being added (length constraints), and the context (JSON Schema compatibility). The title is concise, avoids unnecessary noise, and accurately reflects the primary objective of the changeset.
Description Check ✅ Passed The description is clearly related to the changeset, providing specific information about what's being added (the four new methods: min, max, length, and nonempty), explaining the problem being solved (missing minItems and maxItems in JSON Schema conversion), and describing the benefit (more precise validation). It's not vague or off-topic—it directly connects the implementation to its practical purpose and context.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d336c4 and c58d250.

📒 Files selected for processing (1)
  • packages/zod/src/v4/classic/schemas.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{js,jsx,ts,tsx,mjs,cjs,json}

📄 CodeRabbit inference engine (CLAUDE.md)

Enforce line width of 120 characters via Biome formatting

Files:

  • packages/zod/src/v4/classic/schemas.ts
**/*.{js,jsx,ts,tsx,mjs,cjs}

📄 CodeRabbit inference engine (CLAUDE.md)

Use ES5-style trailing commas in JavaScript/TypeScript code

Files:

  • packages/zod/src/v4/classic/schemas.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Allow the any type in TypeScript (noExplicitAny off)
Allow non-null assertions in TypeScript (noNonNullAssertion off)
Write TypeScript to pass strict mode with exactOptionalPropertyTypes enabled
Use NodeNext module resolution semantics for imports in TypeScript
Target ES2020 language features in TypeScript source

Files:

  • packages/zod/src/v4/classic/schemas.ts
**/*.{ts,tsx,js,jsx,mjs,cjs}

📄 CodeRabbit inference engine (CLAUDE.md)

Allow parameter reassignment for performance-sensitive code (noParameterAssign off)

Files:

  • packages/zod/src/v4/classic/schemas.ts
**/*.{js,mjs,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development-setup.mdc)

**/*.{js,mjs,ts,tsx}: Use .js extensions in import specifiers (e.g., import { z } from "./index.js")
Don’t use require(); use ESM import statements

Files:

  • packages/zod/src/v4/classic/schemas.ts
**/*.{js,mjs,cjs,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/guidelines.mdc)

Do not leave log statements (e.g., console.log, debugger) in tests or production code

Files:

  • packages/zod/src/v4/classic/schemas.ts
packages/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/zod-project-guide.mdc)

Write source code in TypeScript (TypeScript-first codebase)

Files:

  • packages/zod/src/v4/classic/schemas.ts
packages/zod/**

📄 CodeRabbit inference engine (.cursor/rules/zod-project-guide.mdc)

Make core Zod library changes in the main package at packages/zod/

Files:

  • packages/zod/src/v4/classic/schemas.ts
🧠 Learnings (3)
📚 Learning: 2025-10-21T17:27:32.492Z
Learnt from: CR
PR: colinhacks/zod#0
File: .cursor/rules/zod-internals.mdc:0-0
Timestamp: 2025-10-21T17:27:32.492Z
Learning: Applies to packages/zod/src/v4/core/schemas.ts : Wrapper schemas (e.g., $ZodOptional, $ZodNullable, $ZodReadonly) must pass through internal properties from their inner type using util.defineLazy for propValues, values, optin, and optout

Applied to files:

  • packages/zod/src/v4/classic/schemas.ts
📚 Learning: 2025-10-21T17:27:32.492Z
Learnt from: CR
PR: colinhacks/zod#0
File: .cursor/rules/zod-internals.mdc:0-0
Timestamp: 2025-10-21T17:27:32.492Z
Learning: Applies to packages/zod/src/v4/core/{schemas.ts,core.ts} : Use the custom constructor system via core.$constructor() and initialize instances with $ZodType.init() when creating schemas

Applied to files:

  • packages/zod/src/v4/classic/schemas.ts
📚 Learning: 2025-10-21T17:27:32.492Z
Learnt from: CR
PR: colinhacks/zod#0
File: .cursor/rules/zod-internals.mdc:0-0
Timestamp: 2025-10-21T17:27:32.492Z
Learning: Applies to packages/zod/src/v4/core/errors.ts : Define and use canonical error types/codes as declared in errors.ts (e.g., invalid_type, TooBig/TooSmall, InvalidStringFormat, InvalidUnion, Custom)

Applied to files:

  • packages/zod/src/v4/classic/schemas.ts
🧬 Code graph analysis (1)
packages/zod/src/v4/classic/schemas.ts (2)
packages/zod/src/v4/core/api.ts (3)
  • $ZodCheckMinLengthParams (907-907)
  • $ZodCheckMaxLengthParams (894-894)
  • $ZodCheckLengthEqualsParams (919-919)
packages/zod/src/v4/core/core.ts (2)
  • $constructor (7-10)
  • $constructor (17-77)
🔇 Additional comments (2)
packages/zod/src/v4/classic/schemas.ts (2)

1348-1351: Nice addition – consistent with ZodArray API.

The method signatures look solid and match the existing ZodArray pattern perfectly. Enabling length constraints on tuples will definitely help with JSON Schema generation.


1357-1360: Implementation is correct – but verify edge case handling with rest elements.

The methods properly follow the established ZodArray pattern and correctly delegate to the checks module. However, no test cases were found combining rest elements with length constraints (e.g., z.tuple([z.string()]).rest(z.number()).length(1)), which creates semantic ambiguity since rest allows variable length.

The implementation will permit this at schema construction time, but you should manually verify that the runtime validation behaves as intended for these edge cases. Consider adding tests to confirm the behavior is either correctly handled or intentionally unsupported.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant