Documentation issue: Structured Outputs example uses outdated GenAI SDK and Zod APIs

Documentation issue: Structured Outputs example uses outdated GenAI SDK and Zod APIs

Hi everyone,

I found a couple of issues in the JavaScript example on the Structured Outputs documentation page:

Execution Environment

  • OS: Ubuntu 24.04.1 LTS
  • Node.js: v24.14.1
  • @google/genai: v2.7.0

Overview

The current Recipe Extractor example appears to use APIs that are no longer compatible with the latest versions of the @google/genai SDK and zod.

Minimal Reproduction

The documentation currently shows code similar to:

import { GoogleGenAI } from "@google/genai";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";

// (Prompt settings)

const response = await ai.models.generateContent({
  model: "gemini-3.5-flash",
  contents: prompt,
  config: {
    responseFormat: {
      text: {
        mimeType: "application/json",
        schema: zodToJsonSchema(recipeSchema),
      },
    },
  },
});

const recipe = recipeSchema.parse(JSON.parse(response.text));
console.log(recipe);

When running this example with current dependencies, I get:

ReferenceError: zodToJsonSchema is not defined

This appears because zodToJsonSchema is no longer the recommended approach, as Zod now provides native JSON Schema generation.

However, this is only a secondary issue.

Main Issue

The larger problem is that the config structure shown in the documentation does not appear to match the current @google/genai SDK API.

Based on the current GenerateContentConfig type definitions, the example should be closer to:

import { GoogleGenAI } from "@google/genai";
import { z } from "zod";

// (Prompt settings)

const response = await ai.models.generateContent({
  model: "gemini-3.5-flash",
  contents: prompt,
  config: {
    responseMimeType: "application/json",
    responseJsonSchema: z.toJSONSchema(recipeSchema),
  },
});

const recipe = recipeSchema.parse(JSON.parse(response.text));
console.log(recipe);

Suggested Documentation Updates

  1. Replace zodToJsonSchema(...) with Zod’s native JSON Schema support:

    z.toJSONSchema(...)
    
  2. Update the config section to use:

    responseMimeType;
    responseJsonSchema;
    

    instead of:

    responseFormat: {
      text: {
        (mimeType, schema);
      }
    }
    

Could someone confirm whether the documentation is outdated, or if I am missing a compatibility requirement for an older SDK version?

As I could only add two citation URLs in the main topic, I added the references in the reply section.

References

if it merits saying - when rest exists, i use it.
but thats also because some python scares me.

The docs are outdated, and your corrected version is right. Two separate changes landed and the page caught up with neither.

zodToJsonSchema was the community package. Zod 4 ships this natively as z.toJSONSchema(), so that import is no longer needed at all.

On the config shape: responseFormat: { text: { mimeType, schema } } is not in the current GenerateContentConfig. The two fields are responseMimeType and responseJsonSchema, exactly as you wrote. Worth noting alongside that: responseSchema and responseJsonSchema are mutually exclusive. responseSchema takes Gemini’s own Schema object, which is the OpenAPI 3.0 subset with 22 keywords and no reference mechanism at all, while responseJsonSchema takes JSON Schema and does support $id, $defs, $ref and $anchor. If anything ever rejects your $defs, that is the tell that the schema went down the responseSchema path.

One thing worth knowing before you ship the corrected version, because it is silent rather than an error: responseJsonSchema accepts a subset of JSON Schema, and z.toJSONSchema() emits keywords that are not in it. The supported list is $id, $defs, $ref, $anchor, type, format, title, description, enum, items, prefixItems, minItems, maxItems, minimum, maximum, anyOf, oneOf, properties, additionalProperties, required, propertyOrdering. Absent from it: pattern, const, minLength, maxLength, multipleOf, exclusiveMinimum, exclusiveMaximum, uniqueItems.

So a Zod schema using .regex(), .min(), .max(), z.literal() or .multipleOf() produces a JSON Schema whose constraints get dropped rather than enforced. The request succeeds, and the model is then free to return values your own recipeSchema.parse() will reject. I measured this on a five-property schema against a 96-value corpus: the source schema accepted 2 of 96, and the same schema with the unsupported keywords removed accepted all 96.

Two more that catch people on this path:

  • A subschema carrying $ref may not carry any sibling key that does not start with $. So {"$ref": "#/$defs/X", "description": "..."} is rejected — move the description into the definition.
  • Cyclic references are unrolled only to a limited degree, and only within properties that are absent from required. Making the property nullable is not sufficient.

Practical upshot: keep recipeSchema.parse() on the response, which you are already doing. That parse is what actually enforces the constraints the API drops.