-
Notifications
You must be signed in to change notification settings - Fork 635
Description
Describe the bug
When using ai.WithOutputType() with a dynamically created struct where multiple fields share the same Go type, InferJSONSchema produces an invalid JSON Schema that causes the Gemini plugin to fail.
Full error message:
schema is missing the 'type' field: map[string]interface {}{"additionalProperties":true}
The root cause is in internal/base/json.go. The inferSchema function tracks "seen" types to handle recursive references. When a struct type is encountered more than once, it returns:
if seen[t] {
return &jsonschema.Schema{AdditionalProperties: jsonschema.TrueSchema}
}This produces {"additionalProperties": true} which is missing the required type field. The Gemini plugin's toGeminiSchema function in plugins/googlegenai/gemini.go then rejects this schema.
To Reproduce
package main
import (
"context"
"reflect"
"github.com/firebase/genkit/go/ai"
"github.com/firebase/genkit/go/genkit"
"github.com/firebase/genkit/go/plugins/googlegenai"
)
type Message struct {
ID string `json:"id"`
Text string `json:"text"`
}
func main() {
ctx := context.Background()
kit := genkit.Init(ctx, genkit.WithPlugins(&googlegenai.GoogleAI{}))
model := googlegenai.GoogleAIModel(kit, "gemini-2.5-flash")
// Create a dynamic struct with multiple fields of the same type
messageTyp := reflect.TypeFor[Message]()
fields := []reflect.StructField{
{Name: "Key1", Type: messageTyp},
{Name: "Key2", Type: messageTyp}, // Second occurrence triggers the bug
}
outputType := reflect.New(reflect.StructOf(fields)).Interface()
// This will fail with: "schema is missing the 'type' field"
_, err := genkit.Generate(
ctx, kit,
ai.WithModel(model),
ai.WithOutputType(outputType),
ai.WithPrompt("Return two messages"),
)
if err != nil {
panic(err)
}
}Expected behavior
The schema for repeated types should include a type field. For example:
{"type": "object", "additionalProperties": true}Suggested fix in internal/base/json.go:
if seen[t] {
return &jsonschema.Schema{
Type: "object",
AdditionalProperties: jsonschema.TrueSchema,
}
}Screenshots
N/A
Runtime (please complete the following information):
- OS: MacOS
- Version: Sequoia 15.5
- Genkit version: v1.3.0
Go version
go version go1.25.0 darwin/arm64
Additional context
Workaround: Use ai.WithOutputSchema() with a manually constructed schema instead of ai.WithOutputType():
messageSchema := map[string]any{
"type": "object",
"properties": map[string]any{
"id": map[string]any{"type": "string"},
"text": map[string]any{"type": "string"},
},
}
outputSchema := map[string]any{
"type": "object",
"properties": map[string]any{
"Key1": messageSchema,
"Key2": messageSchema,
},
}
_, err := genkit.Generate(
ctx, kit,
ai.WithModel(model),
ai.WithOutputSchema(outputSchema),
ai.WithPrompt("Return two messages"),
)Metadata
Metadata
Assignees
Labels
Type
Projects
Status