Gemini cannot deal with Enums in the JSON schema
I am trying to use Gemini with a schema that includes an Enum and it raises a validation error. The same code works perfectly fine with OpenAI or Together AI models. The MWE below is a combination of the Gemini primer into structured outputs and your own code example for Gemini:
import instructor
from google import genai
from pydantic import BaseModel, ConfigDict
from enum import Enum
class RecipeType(Enum):
DESSERT = 'dessert'
MAIN = 'main'
class Recipe(BaseModel):
recipe_type: RecipeType
ingredients: list[str]
cli = instructor.from_provider(
"google/gemini-2.5-flash", mode=instructor.Mode.GENAI_STRUCTURED_OUTPUTS
# "openai/gpt-4.1-mini"
)
user = cli.chat.completions.create(
messages=[
{
"role": "user",
"content": "Write a recipe.",
},
],
response_model=Recipe,
)
It doesn't matter which mode I choose. Also, the commented out GPT model works perfectly. What also works perfectly is running the same through genai:
from enum import Enum
from google import genai
from pydantic import BaseModel
class RecipeType(Enum):
DESSERT = 'dessert'
MAIN = 'main'
class Recipe(BaseModel):
recipe_type: RecipeType
ingredients: list[str]
client = genai.Client()
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="List a few popular cookie recipes, and include the amounts of ingredients.",
config={
"response_mime_type": "application/json",
"response_schema": list[Recipe],
},
)
# Use the response as a JSON string.
print(response.text)
# Use instantiated objects.
my_recipes: list[Recipe] = response.parsed
So the error is definitely how instructor interfaces with genai. Please look into this, it kind of defeats the purpose of having a unified API if it fails for some providers.
@DavidNemeskey Had this problem as well. I reported it but it was closed. https://github.com/567-labs/instructor/issues/1469
Was told to use strict=False but was worried about side effects. My work-around is I set those enums to str and in the field description I give it the allowed values directly from the enum class. I then have a "public" model that is a copy-paste of the one fed into LLM, but with enum as the types. I have a validator on the internal model that ensures it's a valid value, otherwise instructor will retry. It's annoying boilerplate but preserves the enum-ability for outside callers and preserves the restriction of values to be selected.
@dmastylo but doesn't that completely defeat the purpose of the library, i.e. to be able to access all major LLMs with (almost) the same code?
@DavidNemeskey for most usecases you can use Literals instead of Enums. (also enums get defined at a different place in the json schema, so literals probably result in more reliable outputs as well).
(but agreed that it should "just work" :)