Summary
OpenAPI 3.1 expresses nullability through the type array (["string", "null"]). oasdiff detects nullable transitions for request and response bodies and properties, but the coverage has two gaps. Both are enhancements, not false positives; surfaced while fixing #1004.
Gap 1: parameters have no nullable-change detection
There is no nullable check for parameters (query / path / header) or their object properties. A 3.1 parameter flipping between ["string", "null"] and ["string"] (or toggling the 3.0 nullable field) is not reported as a nullability change anywhere. Request bodies and properties are covered (RequestPropertyBecameNotNullableCheck), but the parameter locations are not.
Gap 2: response "became not nullable" is not recorded
The nullable rules today:
| location |
became-nullable |
became-not-nullable |
| request body / property |
info (non-breaking) |
error (breaking) |
| response body / property |
error (breaking) |
(missing) |
For responses, became-nullable is correctly an error (the client may now receive null) and became-not-nullable is non-breaking. The request side records its non-breaking direction (became-nullable, info), but the response side does not record its non-breaking direction (became-not-nullable). So oasdiff changelog lists "request became nullable" yet omits "response became not nullable", even though both are real backward-compatible changes. Breaking-change detection is unaffected; this is a changelog-completeness asymmetry, and the reason there is no ResponsePropertyBecameNotNullableCheck.
Suggested direction
- Gap 1: add nullable detection for parameters and parameter properties, reusing
nullAddedToTypeArray / nullRemovedFromTypeArray and the nullable field, mirroring the body / property checks.
- Gap 2: have
ResponsePropertyBecameNullableCheck also emit response-body-became-not-nullable / response-property-became-not-nullable at info, so the response side is symmetric with the request side. (Adds new rule IDs, an output-contract addition.)
Summary
OpenAPI 3.1 expresses nullability through the type array (
["string", "null"]). oasdiff detects nullable transitions for request and response bodies and properties, but the coverage has two gaps. Both are enhancements, not false positives; surfaced while fixing #1004.Gap 1: parameters have no nullable-change detection
There is no nullable check for parameters (query / path / header) or their object properties. A 3.1 parameter flipping between
["string", "null"]and["string"](or toggling the 3.0nullablefield) is not reported as a nullability change anywhere. Request bodies and properties are covered (RequestPropertyBecameNotNullableCheck), but the parameter locations are not.Gap 2: response "became not nullable" is not recorded
The nullable rules today:
For responses,
became-nullableis correctly an error (the client may now receivenull) andbecame-not-nullableis non-breaking. The request side records its non-breaking direction (became-nullable, info), but the response side does not record its non-breaking direction (became-not-nullable). Sooasdiff changeloglists "request became nullable" yet omits "response became not nullable", even though both are real backward-compatible changes. Breaking-change detection is unaffected; this is a changelog-completeness asymmetry, and the reason there is noResponsePropertyBecameNotNullableCheck.Suggested direction
nullAddedToTypeArray/nullRemovedFromTypeArrayand thenullablefield, mirroring the body / property checks.ResponsePropertyBecameNullableCheckalso emitresponse-body-became-not-nullable/response-property-became-not-nullableat info, so the response side is symmetric with the request side. (Adds new rule IDs, an output-contract addition.)