Skip to main content
Every failure returns the same JSON envelope, whatever produced it. A single exception filter builds it, so a Prisma error, a guard rejection and a validation failure all look alike to a client.

The envelope

The shape is ApiErrorEnvelope in @asobeast/shared, so a TypeScript client can import it rather than redeclare it.

Status codes

Two of these are worth reading twice. A 504 is produced by the Next.js proxy rather than by the API, so it appears when the API is slow rather than when a request is invalid. The same proxy returns 502 when it cannot reach the API at all. See Web app configuration. A 404 on /docs or /admin/queues is a deliberate answer rather than a missing route. See The queue dashboard and the OpenAPI surface.

Validation errors

Every controller input is a DTO validated by a global pipe with whitelisting on. Two consequences follow.
  • An unknown property is stripped rather than accepted, so a typo in a field name is silently ignored rather than misapplied.
  • A failing field produces a 400 whose message names the field and the rule it broke.
Because unknown properties are stripped rather than rejected, a request that appears to succeed but changed nothing is usually a misspelled field.

API conventions

What the successful responses look like.

Troubleshooting

The same codes seen from the operator side.
Last modified on July 31, 2026