Skip to content

Old renderer with :request: crashes with KeyError: 'properties' for a non-object request body on OAS 3.0 #178

Description

@dstrodtman

The old renderer's :request: option crashes with KeyError: 'properties' when a request body's schema isn't an object. The 3.1 renderer got a guard for this in cca8fc3, but the 3.0 renderer still has the unguarded call, so the same spec crashes on 3.0 and renders on 3.1.

Minimal reproducer

spec.yml — note the requestBody schema is type: string:

openapi: 3.0.3
info:
  title: Minimal
  version: 1.0.0
paths:
  /thing:
    post:
      summary: Create thing
      requestBody:
        content:
          application/json:
            schema:
              type: string
      responses:
        200:
          description: Created.

index.rst:

Page
====

.. openapi:: spec.yml
   :request:

conf.py:

extensions = ["sphinxcontrib.openapi"]

Actual

$ sphinx-build -b html src out
...
  File "sphinxcontrib/openapi/openapi30.py", line 307, in _httpresource
    req_properties = json.dumps(schema['properties'], indent=2,
                                ~~~~~~^^^^^^^^^^^^^^
KeyError: 'properties'

Build aborts, exit 2. Changing only the version to openapi: 3.1.0 makes the same spec render (exit 0), which isolates the cause to the renderer rather than the spec.

Expected

The whole schema dumped as the request body, as the 3.1 renderer already does.

Cause

sphinxcontrib/openapi/openapi30.py line 307 indexes properties unconditionally:

schema = request_content['application/json']['schema']
req_properties = json.dumps(schema['properties'], indent=2,
                            separators=(',', ':'))

A schema that isn't type: object has no properties key. cca8fc3 "Handle non-object request bodies" fixed exactly this in openapi31.py by branching on the type and dumping the whole schema otherwise, but the change wasn't ported to openapi30.py. The two files carry separate copies of this code path.

Note on the fix

Porting the 3.1 guard verbatim gives 3.0/3.1 parity, which seems like the right scope for this issue. Worth flagging that the guard as written in openapi31.py indexes schema["type"] directly, so a schema with no type at all raises KeyError: 'type' on both renderers once ported. That's a pre-existing condition of the 3.1 code rather than something the port introduces, and schema.get('type') would cover it in both files if you'd prefer that as a follow-up.

Happy to open a PR for the port.

Environment

  • sphinxcontrib-openapi 0.9.0
  • sphinxcontrib-httpdomain 2.0.0
  • Sphinx 9.1.0
  • docutils 0.22.4
  • Python 3.12.13

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions