DocTreen
Guides

Error responses

Document possible error responses via the `errors` field.

Document possible error responses via the errors field (available in defineRoute and @DocRoute):

errors: {
  // Plain string — description only
  401: 'Missing or invalid Authorization header',

  // Object — description + error body schema
  422: {
    description: 'Validation failed',
    schema: s.object({ message: s.string(), field: s.string() }),
  },

  // Object — schema only
  500: { schema: s.object({ message: s.string() }) },
}

Error responses appear in each route's detail panel, colour-coded by class (amber for 4xx, red for 5xx), and are exported as saved example responses when downloading a Postman collection — so consumers see exactly what the 422 / 409 / 500 bodies look like.

In the OpenAPI export

Each declared status emits a full responses[N] entry with the schema — spec-driven mocks (including doctreen mock) can then return realistic error payloads when running with --error-rate.

Shared errors with defaultErrors v1.15

Declare shared error responses once at the adapter level instead of repeating them on every route. defaultErrors is keyed by HTTP status and takes the same shape as a route's errors. It's merged into every route, with the route's own errors winning on a status conflict:

expressAdapter(app, {
  defaultErrors: {
    401: 'Authentication required',
    403: 'Forbidden',
    503: 'Service unavailable',
  },
});
// every route now documents 401 / 403 / 503;
// a route's own errors override per status

The validation envelope v1.15

Routes with Zod validators emit a stable 422 contract on failed validation:

{
  "error": "validation_failed",
  "issues": [{ "path": "email", "message": "Required", "code": "invalid_type" }]
}

This shape is documented as a named DoctreenValidationError schema in the OpenAPI export, so consumers can code against it directly. See Runtime validation for how the validators are wired up.

NestJS

@Post()
@DocRoute({
  request:  { body: CreateUser },
  response: User,
  errors: {
    409: 'Email already in use',
    422: { description: 'Validation failed', schema: s.object({ message: s.string() }) },
  },
})
createUser(@Body() body: any) { /* ... */ }

Or compose with the granular decorator:

@DocErrors({ 409: 'Conflict', 422: 'Validation failed' })

On this page