Skip to content

[Docs] # Please document legacyResponseSchema #4104

@christophe-g

Description

@christophe-g

I spent ages trying to understand why calls to googleAI were failing with recent genkit post 1.22. until discovering the legacyResponseSchema option.

Reporting here in case other run into the same error:


GenkitError: Error fetching from https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:generateContent: [400 Bad Request] A schema in GenerationConfig in the request exceeds the maximum allowed nesting depth.

Now my question, why is this relatively simple schema not supported without the legacyResponseSchema flag, and what does the legacyResponseSchema option actually do?

import { genkit, z } from 'genkit';
import { googleAI } from '@genkit-ai/google-genai';
import { describe, it, expect } from 'vitest';
import { geminiApiKey } from "../config.js";

/**
 * REPRODUCTION OF GENKIT ISSUE
 * 
 * Issue: Flow passes with genkit 1.22 but fails with more recent versions.
 * Context: Structured output generation with a Schema.
 */

// 1. Simplified Schema
const questionSchema = z.object({
  code: z.string().describe('The code of the question, camelCase'),
  label: z.string().describe('The question text'),
});

const sectionSchema = z.object({
  title: z.string().optional().describe('Section title'),
  items: z.array(questionSchema).describe('List of questions in the section'),
});

const pageSchema = z.object({
  heading: z.string().describe('Page heading'),
  sections: z.array(sectionSchema).describe('Sections in the page'),
});

const formSchema = z.object({
  title: z.string().describe('Form title to display'),
  pages: z.array(pageSchema).describe('Pages in the form'),
});

// 2. Test Suite
describe('importFormFlow Regression Test', () => {

  const ai = genkit({
    plugins: [
      googleAI({
        apiKey: geminiApiKey,
        legacyResponseSchema: true
      })
    ]
  });
  
  const model = googleAI.model('gemini-3-flash-preview')

  const importFlow = ai.defineFlow(
    {
      name: 'importFlow',
      inputSchema: z.string(), // Input is just a prompt string for this test
      outputSchema: formSchema,
    },
    async (prompt) => {
      const { output } = await ai.generate({
        model,
        prompt: prompt,
        output: { schema: formSchema.or(z.null()) },
      });
      return output;
    }
  );

  it('should successfully parse generated form data', async () => {
    const result = await importFlow('Generate a form');
    
    expect(result).not.toBeNull();
    expect(result?.pages).toHaveLength(1);
    expect(result?.pages[0].sections[0].items).toHaveLength(2);
  });
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsImprovements or additions to documentation

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions