Skip to content

withValidation

withValidation<TEventMap>(registry, options?): Middleware<WebhookEvent>

Defined in: zod/src/index.ts:295

Create a validation middleware using a schema registry

TEventMap extends Record<string, WebhookEvent>

SchemaRegistry<TEventMap>

The schema registry to use for validation

ValidationMiddlewareOptions = {}

Validation options

Middleware<WebhookEvent>

A middleware function

const registry = new SchemaRegistry()
.registerAll({ issueOpened, issueClosed });
const router = new WebhookRouter()
.use(withValidation(registry))
.on('issue.opened', async (event) => {
// event is validated before reaching this handler
});

IMPORTANT: Event Mutation Behavior

This middleware mutates the event object in-place to propagate Zod transformations, defaults, and field stripping to downstream handlers. This is necessary because:

  • The middleware pattern doesn’t support returning a new event object
  • Zod transformations (e.g., .default(), .transform()) must be reflected in handlers
  • Zod’s .strip() mode removes unknown fields that shouldn’t reach handlers

Potential Issues:

  • Multiple middlewares may see inconsistent state if they cache event properties
  • Event references stored before validation will be mutated
  • Property enumeration order may change after validation

Best Practices:

  • Place this middleware early in the chain before other middlewares
  • Don’t cache event properties in middleware that runs before validation
  • Be aware that the event object identity remains the same but contents change

onError Callback Handling:

  • The onError callback is wrapped with try-catch to handle errors gracefully
  • Errors in the callback are logged but do not suppress the original validation error
  • Consider implementing timeout mechanisms in your callback to prevent hanging requests
  • If your callback performs async operations, ensure they complete or timeout appropriately