Structured Response: enums not supported in with Pydantic schema generation

The documentation states that enums are supported:

https://platform.openai.com/docs/guides/structured-outputs/supported-schemas

I’ve tried it with a simple test case but the API rejects the generated schema:

openai.BadRequestError: Error code: 400 - {'error': {'message': "Invalid schema for response_format 'ColorDetection': In context=('properties', 'color'), 'allOf' is not permitted", 'type': 'invalid_request_error', 'param': 'response_format', 'code': None}}`Preformatted text`

test case:

from enum import Enum

from openai import OpenAI
from pydantic import BaseModel, Field


class Color(Enum):
    RED = "red"
    BLUE = "blue"
    GREEN = "green"


class ColorDetection(BaseModel):
    color: Color = Field(description="The detected color")
    hex_color_code: str = Field(description="The hex color code of the detected color")


def test_detect_color():
    client = OpenAI()
    completion = client.beta.chat.completions.parse(
        model="gpt-4o-2024-08-06",
        messages=[
            {
                "role": "user",
                "content": "What color is a Coke can?"
            }
        ],
        response_format=ColorDetection,
    )
    detected = completion.choices[0].message.parsed
    assert detected.color == Color.RED, f"Invalid color detected: {detected}"

generated schema:

 {
  "$defs": {
    "Color": {
      "enum": [
        "red",
        "blue",
        "green"
      ],
      "title": "Color",
      "type": "string"
    }
  },
  "properties": {
    "color": {
      "allOf": [
        {
          "$ref": "#/$defs/Color"
        }
      ],
      "description": "The detected color"
    },
    "hex_color_code": {
      "description": "The hex color code of the detected color",
      "title": "Hex Color Code",
      "type": "string"
    }
  },
  "required": [
    "color",
    "hex_color_code"
  ],
  "title": "ColorDetection",
  "type": "object"
}
1 Like

I think I have a workaround for this in case someone else stumbles on this:

Use a string instead of an enum and declare the enum via json_schema_extra:

color: str = Field(description="The detected color", json_schema_extra={"enum": [Color.RED, Color.BLUE, Color.GREEN]})
2 Likes

Great work!

Thanks for the issue and possible resolution. I’ll make sure this gets seen.

1 Like

Hey @mcantrell, it looks like this is happening because you added a description to the color property.

If you change your models to this, it should work.

from enum import Enum

from openai import OpenAI
from pydantic import BaseModel, Field


class Color(Enum):
    """The dected color"""
    RED = "red"
    BLUE = "blue"
    GREEN = "green"


class ColorDetection(BaseModel):
    color: Color
    hex_color_code: str = Field(description="The hex color code of the detected color")


def test_detect_color():
    client = OpenAI()
    completion = client.beta.chat.completions.parse(
        model="gpt-4o-2024-08-06",
        messages=[
            {
                "role": "user",
                "content": "What color is a Coke can?"
            }
        ],
        response_format=ColorDetection,
    )
    detected = completion.choices[0].message.parsed
    assert detected.color == Color.RED, f"Invalid color detected: {detected}"

Thanks for the bug report, will investigate.

This should be fixed in v1.40.4!

1 Like