Skip to content

Memory leak in generateDocument() when using request parameters #361

@yusukebe

Description

@yusukebe

Hi! We've received the issue about a memory leak for @hono/zod-openapi:

honojs/middleware#1703

I investigated with AI, and I suspect it is caused by this zod-to-openapi. Below is the description of the problem by AI:


Calling generateDocument() repeatedly causes memory to grow continuously because objects are added to the global zodToOpenAPIRegistry. This happens when routes have params, query, or headers in the request config.

Cause

In generateInlineParameters, .openapi() is called on each invocation:

return this.generateParameter(schema.openapi({ param: { name: key, in: location } }))

Since .openapi() creates a new schema instance and adds it to the global registry, memory accumulates with each generateDocument() call.

Reproduction

import { OpenAPIRegistry, OpenApiGeneratorV3 } from '@asteasolutions/zod-to-openapi'
import { z } from 'zod'

const registry = new OpenAPIRegistry()

registry.registerPath({
  method: 'get',
  path: '/users/{id}',
  request: {
    params: z.object({ id: z.string() }),
  },
  responses: { 200: { description: 'OK' } },
})

// Memory keeps growing
for (let i = 0; i < 1000; i++) {
  const generator = new OpenApiGeneratorV3(registry.definitions)
  generator.generateDocument({
    openapi: '3.0.0',
    info: { title: 'Test', version: '1.0.0' },
  })
}

Expected behavior

Memory should remain stable after GC.

Suggested fix

Pass name and in as parameters to generateParameter instead of calling .openapi():

generateParameter(zodSchema, externalParams) {
  const paramName = externalParams?.name ?? paramMetadata?.name
  const paramLocation = externalParams?.in ?? paramMetadata?.in
  // ...
}

// In generateInlineParameters:
return this.generateParameter(schema, { name: key, in: location })

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions