Skip to content

docs: clarify strict Zod function schemas#1988

Open
HAYDEN-OAI wants to merge 1 commit into
mainfrom
codex/document-strict-zod-functions
Open

docs: clarify strict Zod function schemas#1988
HAYDEN-OAI wants to merge 1 commit into
mainfrom
codex/document-strict-zod-functions

Conversation

@HAYDEN-OAI

Copy link
Copy Markdown
Contributor

Summary

  • document that zodFunction() always creates a strict function tool
  • call out that .default() and string .min()/.max() emit keywords outside the strict schema subset
  • point users who need those Zod behaviors to a regular non-strict tool with local Zod parsing

Why

The report in #1119 compared zodFunction() with a custom helper that appeared to work. The difference is that the custom helper sends a non-strict tool, while zodFunction() deliberately opts into strict Structured Outputs. In strict mode, default, minLength, and maxLength can be rejected by the API.

Impact

Users now get an actionable explanation before reaching the API error and can choose the non-strict tool path when their Zod schema depends on defaults or string length constraints. This avoids silently stripping constraints from the model-facing schema while preserving the existing strict helper behavior.

Validation

  • pnpm run format
  • pnpm run lint
  • git diff --check

Resolves #1119

@openai-sdks

openai-sdks Bot commented Jul 9, 2026

Copy link
Copy Markdown

OkTest Summary

Failed for Node SDK PR #1988.

View OkTest run #29052773690

SDK merge (9ada6946c141) · head (a63f7e776650) · base (61539248cbe0) · OkTest (cb7f0514ccd2)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a63f7e7766

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread helpers.md
Comment on lines +69 to +70
`zodFunction()` always creates a strict function tool, use a regular non-strict
tool and parse its arguments with Zod yourself when you need these behaviors.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clarify the non-strict tool path

Because this section documents chat.completions.parse(), this recommendation can lead users to pass a regular non-strict tool back to parse(). That path calls validateInputTools before sending the request and rejects any tool whose function.strict !== true, so the documented workaround fails locally instead of letting users parse the arguments themselves. Please make explicit that this workaround requires .create()/manual tool handling or another non-auto-parsing path rather than .parse().

Useful? React with 👍 / 👎.

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread helpers.md
Custom refinements and transforms still run when the SDK parses the response, but
some schemas that cannot be converted, including bare transforms in Zod v4, cause
the helper to throw before a request is made.
- `.default()` emits the unsupported `default` keyword, and string `.min()` or

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer accurate for the current API. The Structured Outputs guide now documents string length constraints as unsupported only for fine-tuned models, and live calls with the exact schema generated by both Zod v3 and v4 were accepted by gpt-4.1-mini, gpt-4o-2024-08-06, and gpt-4o-mini-2024-07-18 (including default, minLength, and maxLength). The original 2024 rejection is therefore not reproducible today. Please avoid categorically labeling these keywords unsupported or recommending a non-strict tool; at minimum this needs to distinguish fine-tuned models and explain that .default() does not make the field optional because the strict conversion adds it to required. Current reference: https://developers.openai.com/api/docs/guides/structured-outputs#some-type-specific-keywords-are-not-yet-supported

@jbeckwith-oai jbeckwith-oai left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reproduced the schema generation and tested the proposed diagnosis against the current API. Both zod/v3 and zod/v4 generate strict function schemas containing default, minLength, and maxLength, with defaulted fields added to required. However, the original 2024 API rejection is no longer reproducible: live forced-tool calls using that exact generated schema succeeded on gpt-4.1-mini, gpt-4o-2024-08-06, and gpt-4o-mini-2024-07-18. I also tested default and minLength/maxLength separately on gpt-4.1-mini; all were accepted.

The current Structured Outputs guide likewise lists minLength/maxLength as unsupported only for fine-tuned models, not standard models: https://developers.openai.com/api/docs/guides/structured-outputs#some-type-specific-keywords-are-not-yet-supported. As written, this PR would tell users that a working strict schema is unsupported and direct them to give up strict tool calling. It also conflates .default() being emitted/accepted with optionality: strict conversion makes the property required, so a default generally cannot be exercised by a conforming model-generated call.

Local validation: ./node_modules/.bin/jest tests/helpers/zod.test.ts --runInBand (22/22 passed), ./node_modules/.bin/prettier --check helpers.md (passed), and git diff --check origin/main...HEAD (passed). The patch is docs-only and introduces no runtime/type ABI break, but the behavioral guidance is materially incorrect and should be revised before merge. The original issue should likely be closed as no longer reproducible, or any docs should narrowly describe fine-tuned-model limitations and default semantics.

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.

zodFunction helper rejects default() and min() Zod methods in validation schemas for function calling

2 participants