Skip to content

Conversation

@ellis-driscoll
Copy link
Contributor

@ellis-driscoll ellis-driscoll commented Jan 4, 2026

Background

#11078 updated z4. toJSONSchema() in packages/provider-utils/src/schema.ts to use io: 'input' instead of io: 'output'

With io: 'input', zod does not automatically set additionalProperties: false, so addAdditionalPropertiesToJsonSchema was added as a post-processor.

The current implementation only handles objects and arrays of object, so more complex schemas fail with errors like:

error: {
  message: "Invalid schema for response_format 'response': In context=('properties', 'response', 'anyOf', '0'), 'additionalProperties' is required to be supplied and to be false.",
  type: 'invalid_request_error',
  param: 'text.format.schema',
  code: 'invalid_json_schema'
}

Summary

With heavy inspiration from @Jeto143's comment on #11369, this change adds support for schemas with:

  • multiple types e.g., "type": ["object", "null"]
  • anyOf e.g., from z.union()
  • allOf e.g., from z.intersection()
  • oneOf
  • definitions e.g, for recursive schemas

Note, multiple types and oneOf are not currently produced by zod, but I figured it made sense to future proof.

Manual Verification

Running the script below from packages/ai will fail with the error above on main, but runs successfully with this change.

import { generateText, Output } from './src/index.js';
import { createOpenAI } from '../openai/src/index.js';
import { z } from 'zod/v4';

const OPENAI_API_KEY = 'sk-svcacct-...';
const openai = createOpenAI({ apiKey: OPENAI_API_KEY });

const responseSchema = z.object({
  payload: z.discriminatedUnion('kind', [
    z.object({
      kind: z.literal('foo'),
      message: z.string(),
    }),
    z.object({
      kind: z.literal('bar'),
      reason: z.string(),
    }),
  ]),
});

async function main() {
  const { output } = await generateText({
    model: openai('gpt-5-mini'),
    prompt: 'Pick one',
    output: Output.object({ schema: responseSchema }),
  });

  console.log(output);
}

main();

Checklist

  • Tests have been added / updated (for bug fixes / features)
  • Documentation has been added / updated (for bug fixes / features)
  • A patch changeset for relevant packages has been added (for bug fixes / features - run pnpm changeset in the project root)
  • I have reviewed this pull request (self-review)

Related Issues

Fixes #11369

@vercel-ai-sdk vercel-ai-sdk bot added the ai/core label Jan 4, 2026
@ellis-driscoll ellis-driscoll changed the title fix: handle anyOf/allOf/oneOf and definitions in addAdditionalPropert… fix: handle anyOf/allOf/oneOf and definitions in addAdditionalPropertiesToJsonSchema Jan 4, 2026
@ellis-driscoll ellis-driscoll changed the title fix: handle anyOf/allOf/oneOf and definitions in addAdditionalPropertiesToJsonSchema fix(provider-utils): handle anyOf/allOf/oneOf and definitions in addAdditionalPropertiesToJsonSchema Jan 4, 2026
@ellis-driscoll ellis-driscoll marked this pull request as ready for review January 4, 2026 05:42
@lgrammel lgrammel requested a review from Copilot January 5, 2026 18:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a critical issue where schemas with complex structures like anyOf, allOf, oneOf, and definitions were failing validation with OpenAI's API due to missing additionalProperties: false requirements. The fix extends the addAdditionalPropertiesToJsonSchema function to recursively process these schema constructs.

  • Adds support for handling union types (e.g., ["object", "null"])
  • Adds recursive processing of anyOf, allOf, oneOf, and definitions schema constructs
  • Introduces a helper visit function to handle JSONSchema7Definition types (which can be boolean or schema objects)

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
packages/provider-utils/src/add-additional-properties-to-json-schema.ts Extended function to handle complex schema structures including union types, composition operators, and schema definitions with recursive processing
packages/provider-utils/src/add-additional-properties-to-json-schema.test.ts Added three new test cases covering union types, anyOf, and recursive references via definitions
packages/provider-utils/src/__snapshots__/schema.test.ts.snap Updated snapshots to reflect additionalProperties: false now being added to schemas in definitions

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Added tests to ensure that `addAdditionalPropertiesToJsonSchema` correctly sets `additionalProperties: false` for object schemas within `allOf` and `oneOf` constructs in JSON Schema. This enhances the validation of complex schema structures.
@lgrammel lgrammel merged commit 0b429d4 into vercel:main Jan 5, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Zod unions inside schema fail due to missing additionalProperties: false (in strict mode)

2 participants