pactflow / pactflow/openapi-pact-comparator
oneOf validation fails when Pact response body is {}
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 9
- Forks
- 5
- Avg merge
- 2h 26m
- Merged PRs (30d)
- 27
Description
Description
When a Pact interaction's response body is {} (the consumer makes no assertions about the body) and the OpenAPI spec uses oneOf, OPC rejects it with must match exactly one schema in oneOf. OPC is treating {} as a literal empty object to validate against the schema, rather than recognising it as "no assertions". Since {} satisfies neither branch of the oneOf (both require fields), the comparison fails.
This is a false positive: in Pact, an empty body {} means the consumer does not care about the response body at all — it should be treated as compatible with any response schema. Notably, {} validates correctly when the spec defines a regular (non-oneOf) schema for the same response.
Steps to reproduce
openapi.yaml
openapi: 3.0.0
info:
title: OPC oneOf repro
version: 1.0.0
paths:
/test:
post:
responses:
'200':
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/TypeA'
- $ref: '#/components/schemas/TypeB'
components:
schemas:
TypeA:
type: object
required:
- kind
- a_field
properties:
kind:
type: string
a_field:
type: string
TypeB:
type: object
required:
- kind
- b_field
properties:
kind:
type: string
b_field:
type: string
pact.json
{
"consumer": { "name": "test-consumer" },
"provider": { "name": "test-provider" },
"interactions": [
{
"description": "POST /test with empty response body",
"request": { "method": "POST", "path": "/test" },
"response": {
"status": 200,
"body": {}
}
}
]
}
Run:
opc --oas openapi.yaml pact.json
Actual result
[
{
"code": "response.body.incompatible",
"message": "Response body is incompatible with the response body schema in the spec file: must match exactly one schema in oneOf",
"mockDetails": {
"interactionDescription": "POST /test with empty response body",
"interactionState": "[none]",
"location": "[root].interactions[0].response.body",
"value": {}
},
"specDetails": {
"location": "[root].paths./test.post.responses.200.content.application/json.schema.oneOf",
"pathMethod": "post",
"pathName": "/test",
"value": [
{
"$ref": "#/components/schemas/TypeA"
},
{
"$ref": "#/components/schemas/TypeB"
}
]
},
"type": "error"
}
]
Exit code: 1
Expected result
Exit code 0, no errors. {} in a Pact response body means the consumer makes no assertions — it should be a no-op for schema validation, regardless of whether the spec uses oneOf or not.
Workaround
Including at least one field from a oneOf branch in the response body (e.g. { "a_field": "some-value" }) allows OPC to disambiguate and passes validation. This is not always practical — consumers legitimately may not care about the body at all.
Environment
@pactflow/openapi-pact-comparator@2.2.0
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running opc --oas openapi.yaml pact.json with the reproduction files shown in the issue and trace the response-body validation path for Pact bodies. Confirm that an empty {} response exits 0 with no errors for both oneOf and regular schemas, while non-empty bodies retain validation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100