# Structured Outputs: Invalid schema for response\_format, Extra required key supplied \> OpenAI & Zod don't work together for nested structures?

**URL:** <https://community.openai.com/t/structured-outputs-invalid-schema-for-response-format-extra-required-key-supplied-openai-zod-dont-work-together-for-nested-structures/989579>\
**Category:** API\
**Tags:** gpt-4, structured-output\
**Created:** [October 23, 2024, 12:13pm UTC](https://community.openai.com/t/structured-outputs-invalid-schema-for-response-format-extra-required-key-supplied-openai-zod-dont-work-together-for-nested-structures/989579 "2024-10-23T12:13:50Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![marty\_14](https://sea2.discourse-cdn.com/openai1/user_avatar/community.openai.com/marty_14/32/448369_2.png) [@marty\_14](https://community.openai.com/u/marty_14)\
**Post date:** [October 23, 2024, 12:13pm UTC](https://community.openai.com/t/structured-outputs-invalid-schema-for-response-format-extra-required-key-supplied-openai-zod-dont-work-together-for-nested-structures/989579/1 "2024-10-23T12:13:50Z")

</div>

I’m trying to implement Structured Outputs in a Node app (GPT4o, 2024-08-01-preview), but it is giving me the error:

> 400 Invalid schema for response\_format ‘book’: In context=(), ‘required’ is required to be supplied and to be an array including every key in properties. Extra required key ‘chapters’ supplied.

It seems to be pointing to my schema below (simplified here). As I read in the docs, all properties should be listed under `required`, also the optional ones, so that seems correct below (I of course also tried it with different versions for `.required` (and by leaving out `required` completely) but all with the same outcome). If I remove `chapters: z.record(z.string(), ChapterSchema),` the error is gone, but it doesn’t return the chapters. What is wrong with the code below?

```auto
import { AzureOpenAI } from 'openai';
import { z } from 'zod';
import { zodResponseFormat } from 'openai/helpers/zod';

const ChapterSchema = z
  .object({
    title: z.string(),
    subtitle: z.string().nullable(),
  })
  .strict();

export const BookSchema = z
  .object({
    author: z.string(),
    publisher: z.string().nullable(),
    chapters: z.record(z.string(), ChapterSchema),
  })
  .required([
    'author',
    'publisher',
    'chapters',
  ])
  .strict();

const openai = new AzureOpenAI({});
const response = await openai.beta.chat.completions.parse({
    model: process.env.OPENAI_MODEL || '',
    messages: prompt,
    response_format: zodResponseFormat(BookSchema, 'book'),
});

```

**UPDATE:**

If I create the JSON structure manually to send along with the `response`\_format` instead of using zod, it turns out the crucial thing is to include the ChapterSchema _as a definition_ referenced inside the BookSchema. Only then I was able to get it to work.

```auto
const openai = new AzureOpenAI({});
const response = await openai.beta.chat.completions.parse({
    model: process.env.OPENAI_MODEL || '',
    messages: prompt,
    response_format: {
      type: 'json_schema',
      json_schema: {
        name: 'book',
        strict: true,
        schema: {
          type: 'object',
          properties: {
            author: {
              type: 'string',
            },
            publisher: {
              type: ['string', 'null'],
            },
            chapters: {
              type: 'object',
              additionalProperties: {
                $ref: '#/definitions/ChapterSchema',
              },
            },
          },
          // Required only includes 'author' and 'publisher'
          required: ['author', 'publisher'],
          additionalProperties: false,
          definitions: {
            ChapterSchema: {
              type: 'object',
              properties: {
                title: {
                  type: 'string',
                },
                subtitle: {
                  type: ['string', 'null'],
                },
              },
              required: ['title', 'subtitle'],
              additionalProperties: false,
            },
          },
        },
      },
    },
});

```

Hence, it looks like zod, although recommended in the [OpenAI docs](https://platform.openai.com/docs/guides/structured-outputs/introduction?lang=node.js), does not work with OpenAI when using a nested structure, as a nested structure seems to require the use of definitions and definition do not seem to be supported by zod. I hope a senior GPT expert can confirm or contradict?

---

<div class="post-metadata">

**Author:** ![mm11x](https://sea2.discourse-cdn.com/openai1/user_avatar/community.openai.com/mm11x/32/448555_2.png) [@mm11x](https://community.openai.com/u/mm11x)\
**Post date:** [November 6, 2024, 12:40am UTC](https://community.openai.com/t/structured-outputs-invalid-schema-for-response-format-extra-required-key-supplied-openai-zod-dont-work-together-for-nested-structures/989579/2 "2024-11-06T00:40:21Z")

</div>

I also had this problem and thought it could not be solved using zod. Good news! You can keep and use your zod schema (with a small change)!

```auto
export const BookSchema = z.object({
  author: z.string(),
  publisher: z.string().nullable(),
  chapters: z.object({}).catchall(
    z.object({
      title: z.string(),
      subtitle: z.string().nullable(),
    }).strict()
  ),
}).required([
  'author',
  'publisher',
  'chapters',
]).strict();

```

Two issues:

- `z.record()` doesn’t play well with the parser
- referencing a zod schema in another zod schema also doesn’t work well with the parser
