Skip to content

Some implementations cant merge schemas defined in allOf property. #419

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
lukacat10 opened this issue Feb 14, 2025 · 1 comment
Open

Comments

@lukacat10
Copy link

lukacat10 commented Feb 14, 2025

The following exists in the openapi schema:

response_format:
  allOf:
    - $ref: "#/components/schemas/AssistantsApiResponseFormatOption"
    - nullable: true

Which means merging the schemas in the list (detailed here).

In AssistantsApiResponseFormatOption:

AssistantsApiResponseFormatOption:
  description: >
    Specifies the format that the model must output. Compatible with
    [GPT-4o](/docs/models#gpt-4o), [GPT-4
    Turbo](/docs/models#gpt-4-turbo-and-gpt-4), and all GPT-3.5 Turbo models
    since `gpt-3.5-turbo-1106`.


    Setting to `{ "type": "json_schema", "json_schema": {...} }` enables
    Structured Outputs which ensures the model will match your supplied JSON
    schema. Learn more in the [Structured Outputs
    guide](/docs/guides/structured-outputs).


    Setting to `{ "type": "json_object" }` enables JSON mode, which ensures
    the message the model generates is valid JSON.


    **Important:** when using JSON mode, you **must** also instruct the
    model to produce JSON yourself via a system or user message. Without
    this, the model may generate an unending stream of whitespace until the
    generation reaches the token limit, resulting in a long-running and
    seemingly "stuck" request. Also note that the message content may be
    partially cut off if `finish_reason="length"`, which indicates the
    generation exceeded `max_tokens` or the conversation exceeded the max
    context length.
  oneOf:
    - type: string
      description: |
        `auto` is the default value
      enum:
        - auto
      x-stainless-const: true
    - $ref: "#/components/schemas/ResponseFormatText"
    - $ref: "#/components/schemas/ResponseFormatJsonObject"
    - $ref: "#/components/schemas/ResponseFormatJsonSchema"
  x-oaiExpandable: true

No nullable: true is defined.

This means, according to the openapi specification (detailed here) that the value of the nullable is false!

Implementations of openapi parsers that are strict to the specifications I linked to earlier, will throw an exception, because trying to merge schemas that have the same field with different values has undefined, unexpected behaviour.

I guess that in practice, many implementations decided to treat merging a schema which has a property defined and one which doesn't define it in an out-of-spec way, using the value from the schema with the value defined, and completely ignoring the one which didn't define any value. This breaks the specs I linked to earlier, and probably why nobody noticed it before.

Edit 1:
I tried it with oapi-codegen.
Here are my temp fixes:
https://github.com/lukacat10/kin-openapi/tree/nullable-fields
https://github.com/lukacat10/oapi-codegen/tree/nullable-fields

Edit 2:
Sort-of-related issues:
oapi-codegen/oapi-codegen#1898
oapi-codegen/oapi-codegen#1883

@emoses
Copy link

emoses commented Apr 23, 2025

I ran into this as well, here's a minimal repo case:

openapi: 3.0.3
info:
  title: Minimal API
  version: "1.0.0"
paths:
  /get:
    get:
      summary: Get a value
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetResponse'
components:
  schemas:
    GetBaseResponse:
      type: object
      properties:
        value:
          type: string
      readOnly: true
    GetResponse:
      allOf:
        - $ref: '#/components/schemas/GetBaseResponse'
        - description: A description
          # oapi-codegen will fail if the following readOnly isn't set on this otherwise-empty schema
          readOnly: true  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants