Description
Description
When using vertex.tools.codeExecution({}) with Gemini 3 Flash (gemini-3-flash-preview) via @ai-sdk/google-vertex, generateText throws AI_APICallError: Invalid JSON response because the Zod response schema in @ai-sdk/google requires codeExecutionResult.output to be a string, but Gemini 3 Flash omits the output field entirely when code execution produces no text output (e.g., only saves image files).
Reproduction
import { createVertex } from '@ai-sdk/google-vertex';
import { generateText } from 'ai';
const vertex = createVertex();
const { text } = await generateText({
model: vertex('gemini-3-flash-preview'),
tools: {
code_execution: vertex.tools.codeExecution({}),
},
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Examine this image and identify all symbols.' },
{ type: 'file', data: imageBuffer, mediaType: 'image/png' },
],
},
],
});
Actual API response (truncated)
The Vertex API returns HTTP 200 with a valid response, but some codeExecutionResult parts omit the output field:
{
"candidates": [{
"content": {
"role": "model",
"parts": [
{
"executableCode": {
"language": "PYTHON",
"code": "import PIL.Image\nimg = PIL.Image.open('input_file_0.png')\nimg.crop((100, 200, 300, 400)).save('cropped.png')\n"
}
},
{
"codeExecutionResult": {
"outcome": "OUTCOME_OK"
}
}
]
},
"finishReason": "STOP"
}]
}
Note: codeExecutionResult has outcome but no output field. This happens when the executed Python code produces no stdout (e.g., it only saves files via PIL).
Error
AI_APICallError: Invalid JSON response
Cause: AI_TypeValidationError
path: candidates[0].content.parts[1].codeExecutionResult.output
code: invalid_type
expected: string
received: undefined
message: "Invalid input: expected string, received undefined"
Root cause
In src/google-generative-ai-language-model.ts, the content schema defines:
codeExecutionResult: z.object({
outcome: z.string(),
output: z.string(), // <-- required
}).nullish(),
The output field should be optional since the Gemini API omits it when there is no text output:
codeExecutionResult: z.object({
outcome: z.string(),
output: z.string().nullish(), // <-- should be optional
}).nullish(),
The same fix should be applied in the getContentSchema function used by both the responseSchema and chunkSchema.
Versions
ai: 6.0.68
@ai-sdk/google-vertex: 4.0.41
@ai-sdk/google: 3.0.20 (bundled with google-vertex)
- Model:
gemini-3-flash-preview via Vertex AI
Workaround
Custom fetch wrapper on createVertex that patches the missing field:
const vertex = createVertex({
fetch: async (url, init) => {
const response = await globalThis.fetch(url, init);
const contentType = response.headers.get('content-type') ?? '';
if (!contentType.includes('application/json')) {
return response;
}
const body = await response.text();
if (!body.includes('codeExecutionResult')) {
return new Response(body, response);
}
const parsed = JSON.parse(body);
for (const candidate of parsed.candidates ?? []) {
for (const part of candidate?.content?.parts ?? []) {
if (part.codeExecutionResult && part.codeExecutionResult.output === undefined) {
part.codeExecutionResult.output = '';
}
}
}
return new Response(JSON.stringify(parsed), response);
},
});
AI SDK Version
ai: 6.0.68
@ai-sdk/google-vertex: 4.0.41
@ai-sdk/google: 3.0.20 (bundled with google-vertex)
- Model:
gemini-3-flash-preview via Vertex AI
Code of Conduct
Description
Description
When using
vertex.tools.codeExecution({})with Gemini 3 Flash (gemini-3-flash-preview) via@ai-sdk/google-vertex,generateTextthrowsAI_APICallError: Invalid JSON responsebecause the Zod response schema in@ai-sdk/googlerequirescodeExecutionResult.outputto be astring, but Gemini 3 Flash omits theoutputfield entirely when code execution produces no text output (e.g., only saves image files).Reproduction
Actual API response (truncated)
The Vertex API returns HTTP 200 with a valid response, but some
codeExecutionResultparts omit theoutputfield:{ "candidates": [{ "content": { "role": "model", "parts": [ { "executableCode": { "language": "PYTHON", "code": "import PIL.Image\nimg = PIL.Image.open('input_file_0.png')\nimg.crop((100, 200, 300, 400)).save('cropped.png')\n" } }, { "codeExecutionResult": { "outcome": "OUTCOME_OK" } } ] }, "finishReason": "STOP" }] }Note:
codeExecutionResulthasoutcomebut nooutputfield. This happens when the executed Python code produces no stdout (e.g., it only saves files via PIL).Error
Root cause
In
src/google-generative-ai-language-model.ts, the content schema defines:The
outputfield should be optional since the Gemini API omits it when there is no text output:The same fix should be applied in the
getContentSchemafunction used by both theresponseSchemaandchunkSchema.Versions
ai: 6.0.68@ai-sdk/google-vertex: 4.0.41@ai-sdk/google: 3.0.20 (bundled with google-vertex)gemini-3-flash-previewvia Vertex AIWorkaround
Custom
fetchwrapper oncreateVertexthat patches the missing field:AI SDK Version
ai: 6.0.68@ai-sdk/google-vertex: 4.0.41@ai-sdk/google: 3.0.20 (bundled with google-vertex)gemini-3-flash-previewvia Vertex AICode of Conduct