Skip to content

Brain Errors

Brain converts thrown HttpException instances into the standard JSON error envelope via HttpExceptionFilter (apps/brain/src/common/filters/http-exception.filter.ts):

{
"statusCode": 401,
"timestamp": "2026-05-05T12:00:00.000Z",
"path": "/api/character/abc",
"message": "Invalid token"
}

5xx and unexpected errors are forwarded to Sentry. All failures are logged at warn or higher with full request context (correlation id, user id, character id, media id) via nestjs-pino. See Observability for log routing.

HTTP errors

CodeTriggerRemediationReference
401 UnauthorizedInvalid tokenClerk token verification failed (expired, signature, OAuth oat_ exchange failed).Refresh client session; verify CLERK_SECRET_KEY matches the Clerk instance.apps/brain/src/modules/application/auth/strategies/clerk.strategy.ts
401 UnauthorizedNo tokenMissing Authorization header on a non-public route.Caller must send Authorization: Bearer <jwt> (Clerk) or Authorization: Bearer <key> for @ApiKeyRoute().clerk.strategy.ts
401 Unauthorized (api-key)API key not in AUTHORIZED_KEYS.Rotate or extend AUTHORIZED_KEYS; comma-separated string.apps/brain/src/modules/application/auth/strategies/api-key.strategy.ts
403 ForbiddenRole ‘X’ is not authorizedClerk user resolved but lacks roles required by @Roles(...) or default ROOT, ADMIN.Update user role in fennec via user service or sirloin admin tooling.apps/brain/src/modules/application/auth/guards/roles.guard.ts
400 Bad RequestRequest body must include dataPUT /application-settings/:id payload missing top-level data.Wrap payload as { "data": { ... } }.application-settings.http.controller.ts
400 Bad Request (Zod)Application settings body fails Zod schema; message contains formatApplicationSettingsZodError details.Fix payload to match the registered Zod schema for that settings key.application-settings.http.controller.ts
400 Bad Request (class-validator)DTO fails class-validator rules in any controller (CustomValidationPipe).Fix request body / query to satisfy DTO; message is an array of validator errors.apps/brain/src/common/pipes/pipes/custom-validation.pipe.ts
404 Not FoundResource lookups (character, media, generation, tag) returning empty.Verify resource id; confirm caller is querying the right environment.Multiple controllers, generally raised from services.
409 ConflictUnique-constraint violations surfaced from Prisma.Inspect logged err.meta.target; resolve duplicate before retry.Various services; underlying Prisma error code P2002.
501 Not ImplementedEndpoint deprecatedPOST /api/webhook/rp/training is intentionally retired.Stop calling it; RunPod training webhook flow is gone.webhook.http.controller.ts
500 Internal Server Error (HttpExceptionFilter fallback)Any non-HttpException thrown bubbles up.Triage in Sentry / Axiom by correlation_id; reproduce via repro endpoint.http-exception.filter.ts

Round client errors

Round-side failures are wrapped at apps/brain/src/modules/application/round/errors/:

ClassTriggerRemediation
RoundServiceUnavailableExceptiongRPC connection failure / health check fail.Confirm ROUND_HOST; check round Railway service status.
RoundServiceTimeoutExceptionCall exceeded the configured deadline.Re-tune timeout; check round CPU/GPU pressure.
RoundServiceInvalidResponseExceptionRound returned an unexpected proto shape.Regenerate stubs; verify proto compatibility (make generate-proto).
RoundServiceException (base)Generic gRPC error.Inspect inner cause.

A circuit breaker in apps/brain/src/modules/application/round/interceptors/circuit-breaker.interceptor.ts short-circuits round calls after sustained failure — expect RoundServiceUnavailableException while open.

Generation pipeline errors

ClassTriggerRemediation
ContentModerationExceptionHive or internal moderation flagged the input. Logged at warn, not Sentry-paged.Check moderation logs; user-facing message must not leak internal details.
Provider exceptions (FAL / RunPod / Wavespeed / Kling / Vertex)4xx/5xx from upstream provider.Inspect provider logs; check API key validity and quota.
BullMQ stalled jobsWorker crash mid-job; emitted via OnWorkerEvent('stalled') in MediaFlowsProcessor.Inspect Bull Board (/queues); check Redis connection; resume via the dashboard.

Prisma errors

Prisma errors propagate as unknown/Error subtypes; the filter logs them at error and Sentry pages on 5xx.

Prisma codeTriggerRemediation
P2002Unique-constraint violation.Map to 409 Conflict in service; surface offending field.
P2003Foreign-key constraint failed.Validate referenced id exists.
P2025Record not found on update/delete.Map to 404 Not Found.
P1001Cannot reach database.Check DATABASE_URL, network, Neon status.
P1017Server closed connection.Common with pooler; usually transient.

Clerk errors

@clerk/backend wraps issues from Clerk Frontend API:

SymptomTriggerRemediation
oat_ token rejectedOAuth opaque token; Clerk Frontend API /oauth/userinfo exchange failed.Verify CLERK_FRONTEND_API_URL reachable; check Clerk instance domain.
Session JWT rejectedWrong CLERK_SECRET_KEY for issuer.Match secret to the Clerk instance issuing the token.
Network timeoutClerk API outage.Check Clerk status page; Brain has no offline session cache.

BullMQ errors

SymptomTriggerRemediation
Jobs not drainingRedis unreachable or auth wrong.Check REDIS_HOST/PORT/PASSWORD and Railway Redis service.
Jobs marked failed with MaxStalledCountWorker repeatedly crashed.Investigate via Bull Board; restart workers; inspect Sentry for crash stack.
Memory growthBacklog of completed/failed jobs above retention.removeOnComplete / removeOnFail is set in queue.config.ts; raise retention only if needed.

TODO

  • No controller maps Prisma P2002/P2025 to dedicated ConflictException/NotFoundException; unmapped Prisma errors propagate to the global filter as 500 (no PrismaClientKnownRequestError references in apps/brain/src/).
  • ContentModerationException is the sole moderation error subclass under apps/brain/src/modules/domain/generation/errors/; no other moderation subclasses exist (sibling exceptions: application-misconfigured, entity-not-found, entity-unable-to-process).
  • Round circuit-breaker defaults (apps/brain/src/modules/application/round/interceptors/circuit-breaker.interceptor.ts:37-43): errorThresholdPercentage: 50, volumeThreshold: 10, rollingCountTimeout: 10000ms (10 buckets × 1s), resetTimeout: 15000ms (half-open probe), per-call timeout: 35000ms.