Skip to content

Zod transform() causes response schema to lose type information in OpenAPI spec #208

@aon

Description

@aon

Description

When using @fastify/swagger with fastify-type-provider-zod, Zod schemas that include .transform() methods result in incorrect OpenAPI specifications. The transformed fields in response schemas are rendered as empty objects {} instead of maintaining their proper type information, while request schemas work correctly.

Reproduction

Minimal reproduction repository: https://github.com/aon/fastify-swagger-zod-transform-bug

import Fastify from "fastify";
import {
  jsonSchemaTransform,
  serializerCompiler,
  validatorCompiler,
  type ZodTypeProvider,
} from "fastify-type-provider-zod";
import swagger from "@fastify/swagger";
import z from "zod";

const app = Fastify().withTypeProvider<ZodTypeProvider>();

app.setValidatorCompiler(validatorCompiler);
app.setSerializerCompiler(serializerCompiler);

await app.register(swagger, {
  openapi: { openapi: "3.1.0" },
  transform: jsonSchemaTransform,
});

app.post("/", {
  schema: {
    body: z.object({
      string: z.string(),
      stringWithTransform: z.string().transform((v) => v),
    }),
    response: {
      200: z.object({
        string: z.string(),
        stringWithTransform: z.string().transform((v) => v),
      }),
    },
  },
}, async (request, reply) => {
  return reply.status(200).send({
    string: request.body.string,
    stringWithTransform: request.body.stringWithTransform,
  });
});

await app.ready();
console.log(JSON.stringify(app.swagger(), null, 2));

Expected Behavior

Both request and response schemas should maintain type information for transformed fields:

"stringWithTransform": {
  "type": "string"
}

Actual Behavior

  • ✅ Request body schema: Correctly shows "type": "string"
  • ❌ Response schema: Shows empty object {}
{
  "paths": {
    "/": {
      "post": {
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "stringWithTransform": {
                    "type": "string"  // ✅ Correct
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "stringWithTransform": {}  // ❌ Bug: Missing type
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Environment

  • Node version: 22
  • @fastify/swagger: 9.5.1
  • fastify: 5.5.0
  • fastify-type-provider-zod: 6.0.0
  • zod: 4.1.5

Additional Context

This issue makes it impossible to use Zod transforms in response schemas while maintaining accurate OpenAPI documentation. The bug appears to be specific to response schemas, as request schemas handle transforms correctly.

I've reported this issue as well in fastify/fastify-swagger#893

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions