Skip to content

Bug: internal library exception is leaked #511

@balazsszendrodi

Description

@balazsszendrodi

Hello, thank you for maintaining this project!

Description

I found an issue, where an internal library error (referencing lib) is raised and not wrapped in a ValidationError. Also this exception logs the whole of the openapi spec which is not ideal for a really large spec.

Expected behavior

The internal ValidationError exception is raised instead of the internal library one.

Steps to Reproduce

Here is minimal openapi spec to reproduce the issue.

# openapi.invalid_reference.yml
openapi: 3.0.0
info:
  title: Trigger unhandled exception
  version: 1.0.0
  description: >-
    This is a minimal openapi config to trigger referencing.exceptions.PointerToNowhere
    exception this should be handled by the openapi_spec_validator but it is not
servers:
  - url: http://petstore.swagger.io/api
paths:
  /pets:
    get:
      responses:
        "200":
          description: pet response
        "401": # Reference points to nonexistant entry, this should trigger the exception
          $ref: "#/components/responses/InvalidReference"
        "5XX":
          $ref: "#/components/responses/APIError"

components:
  responses:
    APIError:
      description: An error occurred interacting with the API.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/APIError"
# main.py
from openapi_spec_validator import validate
from openapi_spec_validator.readers import read_from_filename

spec_dict, base_uri = read_from_filename('openapi.invalid_reference.yml')
# referencing.exceptions.PointerToNowhere exception is raised
validate(spec_dict)

Raised exception output

Traceback (most recent call last):
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/referencing/_core.py", line 276, in pointer
    contents = contents[segment]  # type: ignore[reportUnknownArgumentType]
               ~~~~~~~~^^^^^^^^^
KeyError: 'InvalidReference'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/user/repro/schema_validation/main.py", line 6, in <module>
    validate(spec_dict)
    ~~~~~~~~^^^^^^^^^^^
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/openapi_spec_validator/shortcuts.py", line 55, in validate
    return v.validate()
           ~~~~~~~~~~^^
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/openapi_spec_validator/validation/validators.py", line 72, in validate
    for err in self.iter_errors():
               ~~~~~~~~~~~~~~~~^^
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/openapi_spec_validator/validation/caches.py", line 61, in __next__
    item = next(self.parent)
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/openapi_spec_validator/validation/caches.py", line 30, in __next__
    item = next(self.iter)
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/openapi_spec_validator/validation/decorators.py", line 28, in wrapper
    for err in errors:
               ^^^^^^
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/openapi_spec_validator/validation/validators.py", line 93, in iter_errors
    yield from self.root_validator(self.schema_path)
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/openapi_spec_validator/validation/keywords.py", line 721, in __call__
    yield from self.paths_validator(paths)
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/openapi_spec_validator/validation/keywords.py", line 631, in __call__
    yield from self.path_validator(url, path_item)
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/openapi_spec_validator/validation/keywords.py", line 588, in __call__
    yield from self.operation_validator(
        url, field_name, operation, parameters
    )
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/openapi_spec_validator/validation/keywords.py", line 515, in __call__
    yield from self.responses_validator(responses)
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/openapi_spec_validator/validation/keywords.py", line 475, in __call__
    yield from self.response_validator(response_code, response)
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/openapi_spec_validator/validation/keywords.py", line 462, in __call__
    if "content" in response:
       ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/pathable/paths.py", line 524, in __contains__
    return self.accessor.contains(self.parts, key)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/jsonschema_path/accessors.py", line 178, in contains
    node = self[parts]
           ~~~~^^^^^^^
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/jsonschema_path/accessors.py", line 129, in __getitem__
    resolved = self.get_resolved(parts)
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/jsonschema_path/accessors.py", line 239, in get_resolved
    result = self._path_resolver.resolve(self.node, parts)
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/jsonschema_path/resolvers.py", line 34, in resolve
    resolved = self._resolve_with_prefix_cache(node, parts)
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/jsonschema_path/resolvers.py", line 80, in _resolve_with_prefix_cache
    resolved_schema = SchemaNode._resolve_node(
        current_node,
        current_resolver,
    )
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/jsonschema_path/nodes.py", line 24, in _resolve_node
    resolved = resolver.lookup(ref)
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/referencing/_core.py", line 690, in lookup
    return retrieved.value.pointer(pointer=fragment, resolver=resolver)
           ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/repro/schema_validation/.venv/lib/python3.14/site-packages/referencing/_core.py", line 279, in pointer
    raise error from lookup_error
referencing.exceptions.PointerToNowhere: '/components/responses/InvalidReference' does not exist within {'openapi': '3.0.0', 'info': {'title': 'Trigger unhandled exception', 'version': '1.0.0', 'description': 'This is a minimal openapi config to trigger referencing.exceptions.PointerToNowhere exception this should be handled by the openapi_spec_validator but it is not'}, 'servers': [{'url': 'http://petstore.swagger.io/api'}], 'paths': {'/pets': {'get': {'responses': {'200': {'description': 'pet response'}, '401': {'$ref': '#/components/responses/InvalidReference'}, '5XX': {'$ref': '#/components/responses/APIError'}}}}}, 'components': {'responses': {'APIError': {'description': 'An error occurred interacting with the API.', 'content': {'application/json': {'schema': {'$ref': '#/components/schemas/APIError'}}}}}}}

Environment

  • OS: Linux ubuntu 24.04.1
  • Python version (python --version) : Python 3.14.4
  • python library environment (uv pip freeze):
annotated-types==0.7.0
attrs==26.1.0
jsonschema==4.26.0
jsonschema-path==0.5.0
jsonschema-specifications==2025.9.1
lazy-object-proxy==1.12.0
openapi-schema-validator==0.9.0
openapi-spec-validator==0.9.0
pathable==0.6.0
pydantic==2.13.4
pydantic-core==2.46.4
pydantic-settings==2.14.1
python-dotenv==1.2.2
pyyaml==6.0.3
referencing==0.37.0
rfc3339-validator==0.1.4
rpds-py==2026.5.1
six==1.17.0
typing-extensions==4.15.0
typing-inspection==0.4.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions