Skip to content

Conversation

@bas0N
Copy link

@bas0N bas0N commented Nov 22, 2025

Fastify requires a body when schema.body is defined, even if all properties are optional. This ensures the OpenAPI spec correctly reflects Fastify's runtime behavior. This solves the issue #894

Problem

When a route has schema.body defined, Fastify requires that the request includes a body (at least {}), even if all properties inside that body are optional. However, the OpenAPI schema generated by @fastify/swagger was only setting requestBody.required to true when there were required properties inside the object. If the object had only optional properties, then requestBody.required was omitted, incorrectly marking the request body as optional.

This mismatch between the OpenAPI spec and Fastify's actual runtime behavior can mislead client code generators and API consumers.

Solution

This fix ensures that requestBody.required is always set to true when schema.body is defined, regardless of whether any properties inside the body are required. The fix sets required: true when creating the requestBody object in prepareOpenapiMethod, making it explicit that the body is required whenever a body schema is defined.

Example

Before (incorrect):

{
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "properties": {
            "hello": { "type": "string" }
          }
        }
      }
    }
  }
}

After (correct):

{
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "properties": {
            "hello": { "type": "string" }
          }
        }
      }
    }
  }
}

Changes

  • Set required: true when creating requestBody object in prepareOpenapiMethod
  • Added test case for body with only optional properties
  • Updated existing tests to expect required: true when schema.body is defined

Fixes the issue where the OpenAPI spec incorrectly showed requestBody as optional when Fastify actually requires it at runtime.

Checklist

…y exists

Fastify requires a body when schema.body is defined, even if all properties
are optional. This ensures the OpenAPI spec correctly reflects Fastify's
runtime behavior.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a mismatch between Fastify's runtime validation behavior and the generated OpenAPI specification for request bodies. When a route has schema.body defined, Fastify requires a body to be present (at least {}), even if all properties are optional. The fix ensures requestBody.required is always set to true when schema.body exists.

Key changes:

  • Modified prepareOpenapiMethod to set required: true when creating the requestBody object
  • Removed conditional required logic from resolveBodyParams that only set it when there were required properties
  • Added comprehensive test coverage for the optional-properties case

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
lib/spec/openapi/utils.js Sets requestBody.required = true unconditionally when schema.body is defined, removing the previous conditional logic based on required properties
test/spec/openapi/option.test.js Adds new test case verifying that requestBody.required is true even when all body properties are optional
test/spec/openapi/schema.test.js Updates existing test assertions to expect required: true in all requestBody objects

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@bas0N
Copy link
Author

bas0N commented Nov 25, 2025

@Fdawgs when you get a moment, could you please take a look at this PR? Thanks!

@Fdawgs Fdawgs requested a review from a team November 26, 2025 13:33
Copy link
Contributor

@ilteoood ilteoood left a comment

Choose a reason for hiding this comment

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

LGTM
but honestly I think that on the user perspective this could be considered as a breaking change.
Imagine if someone is generating TS types from the fastify's schema: objects that before were not required, now are flagged as required 🤔

Copy link
Member

@gurgunday gurgunday left a comment

Choose a reason for hiding this comment

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

lgtm

@bas0N
Copy link
Author

bas0N commented Dec 1, 2025

@gurgunday @Fdawgs can we merge it ?

@gurgunday
Copy link
Member

Not sure if we should count this as a bug fix or semver major

I lean towards the latter

Cc @mcollina

@bas0N
Copy link
Author

bas0N commented Dec 11, 2025

@Fdawgs @gurgunday just a quick bump — anything else needed before we merge?

@bozzaj
Copy link

bozzaj commented Jan 15, 2026

Hello team! Any chance that this can be merged sometime soon? Regarding the notes above regarding this being a breaking change. It's important to note that this package is specific to Fastify, and the current implementation is actually broken. For quite some time we've been manually fixing things.

@ilteoood mentioned that "objects that before were not required are now flagged as required". While that's correct when focusing only on this package, it's important to state that the objects that were not required were actually ALWAYS required due to how Fastify works. In any case where there was a body defined, the Fastify API would generate a 400 error if no body was sent. So while the generated code that came out of the OpenAPI spec would have an optional body, in reality it has never been optional. The generated API from this plugin has always been broken in this respect, so any usage of the API that backed the generation would always fail if there was a body defined.

While it could be said that following proper semver processes, this could be considered a breaking change, I would challenge that simply because the current generated code is broken - it does not create a valid specification based on how Fastify works. Since this is a plugin specific to Fastify, and everyone using Fastify MUST pass at least an empty object when a body is defined, this really is fixing a bug so the generated code matches the expectations of Fastify.

Either way - bug fix or major version - it would be nice to not have to patch the package to provide valid functionality, so I appreciate if this PR could be looked at again!

Sorry for the long-winded comment!

@gurgunday gurgunday requested a review from a team January 17, 2026 15:56
@Bram-dc
Copy link
Contributor

Bram-dc commented Jan 22, 2026

This is not only a fix for schemas where all props are optional, but also for ones where we use a ref to another schema that has even only required props.

+1

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.

6 participants