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 statusThe 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' })