-
Notifications
You must be signed in to change notification settings - Fork 444
Open
Labels
Description
Describe the bug
Schema containing zod.literals
seem to break schema, with error message difficult to interpret
To Reproduce
For instance:
// run this through `pnpx tsx test.ts`
import { gemini25FlashPreview0417, googleAI } from '@genkit-ai/googleai';
import { genkit, z } from 'genkit';
const optionSchema = z.object({
locale: z.object({
label: z.string().describe('The text/label of the option'),
supportingText: z.string().optional().describe('The supporting text of the option'),
}),
description: z.string().optional().describe('The description of the option'),
}).describe('The option for a question');
// Base schema with common fields including the locale structure
const baseQuestionSchema = z.object({
locale: z.object({
label: z.string().describe('The text/label of the question being asked'),
supportingText: z.string().optional().describe('The supporting text of the question'),
}),
items: z.array(optionSchema).optional().describe('The options for the checkbox question'),
description: z.string().optional().describe('The description of the question'),
type: z.string().describe('The type of the question'),
// type: z.enum(['text', 'textarea', 'number']).describe('The type of the question'),
});
export const textItemSchema = z.object({
type: z.literal('text'),
locale: z.object({
content: z.string().describe('text content of the presentation item'),
}),
description: z.string().optional().describe('The description of the option'),
}).describe('a text item, containing text content in markdown format');
export const sectionSchema = z.object({
type: z.literal('section'),
locale: z.object({
heading: z.string().optional().describe('The heading of the section'),
}),
description: z.string().optional().describe('The description of the option'),
items: z.array(baseQuestionSchema).describe('The questions or presentation items in the section'), // Allow both questions and presentation items
// items: z.array(z.union([questionSchema, textItemSchema])).describe('The questions or presentation items in the section'), // Allow both questions and presentation items
}).describe('The section containing questions or presentation items');
export const pageSchema = z.object({
type: z.literal('page').describe('Type for the page'),
locale: z.object({
heading: z.string().describe('The heading/title of the page'),
}),
description: z.string().optional().describe('The description of the option'),
items: z.array(sectionSchema).describe('The sections in the page'),
}).describe('The page containing sections');
export const formSchema = z.object({
type: z.literal('form').describe('Type for the form'),
locale: z.object({
heading: z.string().describe('title of the form'),
}),
description: z.string().optional().describe('The description of the option'),
items: z.array(pageSchema).describe('The pages in the form'),
}).describe('The form containing pages');
const systemPromptForForm = `
You are a editor of a Form. A Form is a collection of pages, sections, questions and text.
Each page has heading. Each page has section items. Each page can have a description.
Each section can have a heading and a description. Section group questions together under a common theme.
Section also contain text items written in markdown. A text item is a presentation item, it only contains content.
Question types can be one of the following: text, textarea, number.
`
const ai = genkit({
plugins: [googleAI({ apiKey: process.env.GEMINI_API_KEY! })],
model: gemini25FlashPreview0417, // set default model
});
async function main() {
// make a generation request
const { text } = await ai.generate({
model: gemini25FlashPreview0417,
system: systemPromptForForm,
prompt: `Create a form that will be used to collect data from users about satisfaction with their current workplace.`,
output: { schema: formSchema },
});
console.log(text);
}
main();
produces:
Restarting 'src/ai/generateForm.ts'
Shutting down all Genkit servers...
node:internal/process/promises:394
triggerUncaughtException(err, true /* fromPromise */);
^
GoogleGenerativeAIFetchError: [GoogleGenerativeAI Error]: Error fetching from https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-04-17:generateContent: [400 Bad Request] Invalid JSON payload received. Unknown name "const" at 'generation_config.response_schema.properties[0].value': Cannot find field.
Invalid JSON payload received. Unknown name "const" at 'generation_config.response_schema.properties[3].value.items.properties[0].value': Cannot find field.
Invalid JSON payload received. Unknown name "const" at 'generation_config.response_schema.properties[3].value.items.properties[3].value.items.properties[0].value': Cannot find field. [{"@type":"type.googleapis.com/google.rpc.BadRequest","fieldViolations":[{"field":"generation_config.response_schema.properties[0].value","description":"Invalid JSON payload received. Unknown name \"const\" at 'generation_config.response_schema.properties[0].value': Cannot find field."},{"field":"generation_config.response_schema.properties[3].value.items.properties[0].value","description":"Invalid JSON payload received. Unknown name \"const\" at 'generation_config.response_schema.properties[3].value.items.properties[0].value': Cannot find field."},{"field":"generation_config.response_schema.properties[3].value.items.properties[3].value.items.properties[0].value","description":"Invalid JSON payload received. Unknown name \"const\" at 'generation_config.response_schema.properties[3].value.items.properties[3].value.items.properties[0].value': Cannot find field."}]}]
at handleResponseNotOk (/home/christophe/Programming/preignition/app/app-survey/functions/node_modules/.pnpm/@[email protected]/node_modules/@google/generative-ai/dist/index.js:434:11)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async makeRequest (/home/christophe/Programming/preignition/app/app-survey/functions/node_modules/.pnpm/@[email protected]/node_modules/@google/generative-ai/dist/index.js:403:9)
at async generateContent (/home/christophe/Programming/preignition/app/app-survey/functions/node_modules/.pnpm/@[email protected]/node_modules/@google/generative-ai/dist/index.js:867:22)
at async ChatSession.sendMessage (/home/christophe/Programming/preignition/app/app-survey/functions/node_modules/.pnpm/@[email protected]/node_modules/@google/generative-ai/dist/index.js:1210:9)
at async callGemini (/home/christophe/Programming/preignition/app/app-survey/functions/node_modules/.pnpm/@[email protected][email protected]/node_modules/@genkit-ai/googleai/src/gemini.ts:1045:26)
at async <anonymous> (/home/christophe/Programming/preignition/app/app-survey/functions/node_modules/.pnpm/@[email protected][email protected]/node_modules/@genkit-ai/googleai/src/gemini.ts:1102:11)
at async <anonymous> (/home/christophe/Programming/preignition/app/app-survey/functions/node_modules/.pnpm/@[email protected]/node_modules/@genkit-ai/core/src/action.ts:439:14)
at async <anonymous> (/home/christophe/Programming/preignition/app/app-survey/functions/node_modules/.pnpm/@[email protected]/node_modules/@genkit-ai/core/src/action.ts:335:26)
at async <anonymous> (/home/christophe/Programming/preignition/app/app-survey/functions/node_modules/.pnpm/@[email protected]/node_modules/@genkit-ai/core/src/tracing/instrumentation.ts:73:16) {
status: 400,
statusText: 'Bad Request',
errorDetails: [
{
'@type': 'type.googleapis.com/google.rpc.BadRequest',
fieldViolations: [
{
field: 'generation_config.response_schema.properties[0].value',
description: `Invalid JSON payload received. Unknown name "const" at 'generation_config.response_schema.properties[0].value': Cannot find field.`
},
{
field: 'generation_config.response_schema.properties[3].value.items.properties[0].value',
description: `Invalid JSON payload received. Unknown name "const" at 'generation_config.response_schema.properties[3].value.items.properties[0].value': Cannot find field.`
},
{
field: 'generation_config.response_schema.properties[3].value.items.properties[3].value.items.properties[0].value',
description: `Invalid JSON payload received. Unknown name "const" at 'generation_config.response_schema.properties[3].value.items.properties[3].value.items.properties[0].value': Cannot find field.`
}
]
}
],
traceId: '36cf7d26589b35ed1965c2ee010dd081'
}
Node.js v23.6.1
Failed running 'src/ai/generateForm.ts'
Expected behavior
- zod basic features are not breaking schema parting
- errors message convey useful information
Runtime (please complete the following information):
- OS: Linux mint latest
- Version [e.g. 22]
** Node version
- 23.6.1
Additional context
For others hitting this, using enums as Literals seem to work better:
const typeEnums = z.enum([
'text',
'textarea',
'number',
'radio',
'checkbox',
'dropdown',
'rating',
'textfield',
'tel',
'date',
'email',
'url',
'option',
'section',
'page',
'form',
])
...
export const pageSchema = z.object({
type: typeEnums.extract(['page']).describe('Type for the section'),
locale: z.object({
heading: z.string().describe('The heading/title of the page'),
}),
description: z.string().optional().describe('The description of the option'),
items: z.array(sectionSchema).describe('The sections in the page'),
}).describe('The page containing sections');
louiskhub, JarnoRFB, fwal and adamkoch
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
No status