Skip to content

Fix properties becoming required when a sibling uses allOf - #475

Merged
Carapacik merged 1 commit into
Carapacik:mainfrom
oha-4:oha-4/fix-allof-required
Oct 30, 2026
Merged

Carapacik merged 1 commit into
Carapacik:mainfrom
oha-4:oha-4/fix-allof-required

Conversation

@oha-4

@oha-4 oha-4 commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #460.

For an OpenAPI 3 schema without a required array, every property was generated as required as soon as any one property used allOf. Per the spec, a property that is not listed in required is optional, regardless of how its siblings are declared. @nestjs/swagger emits allOf: [{ $ref }] for every named enum reference and for nullable DTO references, so a NestJS backend hits this on most request DTOs. In our contract it turned optional fields such as String? fcmToken into required String? fcmToken.

The hasAllOfKey check was added in #329, which switched required-ness from "not nullable" to "listed in required". It kept the previous output of NullableUserDto in the all_of.3.0 e2e test (data: allOf [$ref UserDto, {nullable: true}]), not a behavior that allOf composition relies on. Schema-level allOf composition is resolved separately and is unaffected.

Changes:

  • OpenApiParser: remove hasAllOfKey, so only the required array and default decide required-ness.
  • test/parser/all_of_property_not_required_test.dart: schemas without a required array, one with an allOf object reference and one with a nullable allOf enum reference; asserts every property is optional. Fails without the fix.
  • all_of.3.0 e2e expectation: NullableUserDto.data becomes @JsonKey(includeIfNull: false) UserDto? data, the same output as other optional nullable properties.
  • CHANGELOG.md: add a 1.45.1 entry. pubspec.yaml is left for the release commit, as in Infer nullability from OpenAPI 3.1 type lists when inferring required #472.

dart format, dart analyze and the full dart test suite (432 passed, 2 skipped) pass.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@oha-4
oha-4 marked this pull request as ready for review October 24, 2026 03:59
Copilot AI balanced review requested due to automatic review settings October 24, 2026 03:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

@Carapacik
Carapacik self-requested a review October 28, 2026 23:07
@Winget-Software

Copy link
Copy Markdown

This also affects us. We have a NestJS backend whose spec is generated by @nestjs/swagger (OpenAPI 3.0.0), and our PATCH DTOs hit this every time. @nestjs/swagger wraps a $ref in allOf whenever the property has sibling keys such as description or nullable. The latest release (12.0.5) still does this (lib/utils/wrap-ref-in-all-of.util.ts), so upgrading the backend doesn't avoid it.

Minimal schema (no required array):

UpdateAppointmentDto:
  type: object
  properties:
    recurringRuleData:
      nullable: true
      allOf:
        - $ref: '#/components/schemas/UpdateRecurringRuleDto'
    notes:
      type: string
      nullable: true
    reminderEnabled:
      type: boolean
      default: false

On current main (freezed, include_if_null: true):

@JsonKey(includeIfNull: true)
required UpdateRecurringRuleDto? recurringRuleData,
@JsonKey(includeIfNull: true)
required String? notes,
@Default(false)
bool reminderEnabled,

With this PR:

@Default(false)
bool reminderEnabled,
@JsonKey(includeIfNull: false)
UpdateRecurringRuleDto? recurringRuleData,
@JsonKey(includeIfNull: false)
String? notes,

I checked out the PR branch and regenerated our models, and the output above is correct. Both fields are optional again and get omitted from the PATCH body when unset. Properties with default still generate as @Default(...) non-nullable fields, which is what we expect.

We've been carrying this fix in a fork, so we'd be glad to see this merged. Thanks!

@Carapacik
Carapacik merged commit 318e9a4 into Carapacik:main Oct 30, 2026
3 checks passed
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

Successfully merging this pull request may close these issues.

OAS3 schema with no required and an allOf property produces wrongly-required fields

4 participants