Skip to content

Brisket Error Catalogue

Brisket surfaces errors in three layers:

  1. Next.js framework — RSC render, route-handler exceptions, middleware redirects.
  2. tRPC — typed errors with code, message, and a data.zodError field for input validation failures.
  3. Upstream — Connect/gRPC errors from sirloin (code numeric), Strapi/Intercom HTTP errors, Clerk webhook signature failures.

All tRPC procedure failures serialize through the errorFormatter in apps/brisket/src/server/api/trpc.ts:

{
"shape": {
"message": "string",
"code": -32603, // JSON-RPC code mapped from TRPCError code
"data": {
"code": "BAD_REQUEST", // TRPCError code string
"httpStatus": 400,
"path": "subscription.createPrimerCheckout",
"stack": "...", // dev only
"zodError": { // present when input validation fails
"formErrors": [],
"fieldErrors": { "itemPriceId": ["Required"] }
}
}
}
}

Clients should branch on error.data.code (string), not the JSON-RPC numeric code.

# Source Code / Symptom Trigger User-Visible Mitigation
1 tRPC UNAUTHORIZED Clerk session missing/expired on a protectedProcedure. Auto-redirect to /sign-in via middleware; mid-flight tRPC calls surface as a toast. Re-auth. Verify CLERK_SECRET_KEY and clock skew.
2 tRPC BAD_REQUEST with data.zodError Zod input validation failure (e.g. malformed character_id). Inline form error using fieldErrors. Client should pre-validate; check schema in router.
3 tRPC INTERNAL_SERVER_ERROR Uncaught throw in a procedure (sirloin offline, Strapi 5xx, etc.). Generic toast; error telemetry. Inspect error logs and the trpc.${type}.${path} span in Axiom.
4 sirloin Connect code: 5 (NotFound) Subscription / character missing. Subscription router rethrows as Error("No subscription found for user"). Empty state UI / billing onboarding redirect. Expected for new users.
5 sirloin Connect code: 4 (DeadlineExceeded) gRPC > 120 s (default defaultTimeoutMs in sirloin-api.ts). Toast: “Something went wrong, please try again.” Retry; investigate sirloin latency.
6 sirloin Connect code: 14 (Unavailable) sirloin pod restart / network blip. Toast. Transport refresh runs every 30 min; manual retry usually clears it.
7 Cloudflare Turnstile Error("Security check failed. Please try again.") subscription.createPrimerCheckout token verification failed (verifyCfTurnstileToken). Modal asks to re-prove. Re-issue widget; check CF_TURNSTILE_SECRET_KEY.
8 Subscription Error("This plan is not available for your account.") NSFW plan selected without nsfw-onboarding PostHog flag. Plan-selector error banner. Verify flag rollout in PostHog.
9 Clerk webhook 400 Invalid signature Svix HMAC verification failed in /api/webhook/clerk. Webhook source sees retries. Verify CLERK_WEBHOOK_SECRET parity between Clerk dashboard and deploy.
10 Strapi Error("Failed to load FAQ section (${status})") Non-2xx from Strapi in faq.getCheckoutFaqSection. Checkout FAQ accordion empty. Check Strapi uptime and STRAPI_TOKEN.
11 Strapi Zod parse failure on FAQ schema Strapi returned an unexpected shape. Same as #10. Sync schema with chuck content model.
12 Intercom Soft-fail (logger.warn) Missing token, missing email, or contact not found. No user-visible error — support widget silently no-ops. Verify INTERCOM_API_TOKEN; ensure user has primary email.
13 Next.js middleware Redirect to /sign-in?redirect_url=... Hitting a non-public route while logged out. Page navigation to sign-in. Expected.
14 Next.js middleware 404 on /auth-content/* Logged-out request to private asset. 404. Expected — gates private media.
15 Next.js middleware Redirect to /explore Logged-in user hits /sign-in or /sign-up; or invalid redirect_url query. Page navigation to /explore. validateRedirectUrl defends against open-redirect.
16 Next.js RSC Error: Cannot read properties of undefined Frequently a stale Turbopack chunk after dependency change. Full-page error boundary. pnpm --filter brisket build fresh; clear .next/.
17 Next.js digest errors in production Uncaught render error with hashed digest. Generic “Something went wrong”. Search the digest in Axiom logs and correlate the server error.
18 OTel Failed to export traces/logs Bad BRISKET_OTEL_* headers (Axiom 401). None visible to user; observability gap. Re-issue Axiom token; redeploy.
19 Vitest (CI) Timeout / flake on pnpm test Network or fake-timer regression. CI red. Re-run; pin offending test.
20 Build Invalid environment variables: ... (Zod) Required server/client var missing. Build fails. Compare with brisket-env; fill secrets.
21 Build Module not found after pnpm overrides change React 19 / pkg override mismatch. Build fails. pnpm install after pulling; nuke .next/ and node_modules/.
22 Browser Chargebee.js script load failure NEXT_PUBLIC_CHARGE_BEE_SITE or publishable key wrong / network blocked. Checkout cannot mount. Check site slug; corporate proxies sometimes block *.chargebee.com.
23 Browser Clerk publishable key mismatch Stage env points at different Clerk instance than backend CLERK_SECRET_KEY. Sign-in loops. Pair publishable+secret per stage.
24 Browser PostHog blocked by ad-blockers posthog.capture no-ops. None visible; analytics gap. Expected; do not error.
25 Subscription reactivateSubscription rejection (logged) Sirloin rejects reactivation during downgrade detection in createPrimerCheckout. Checkout still proceeds; non-fatal. Inspect logs for Error reactivating subscription.
  • tRPC traces — Axiom dataset beef-staging / beef-prod, span name trpc.${type}.${path} (set in tracingMiddleware).
  • Axiom error logs: server errors use the existing Pino/OTel path. Browser errors use /api/telemetry. Search browser reports by digest, path, and release. Browser stacks remain raw; automatic source-map symbolication is not provided.
  • PostHog — only tracks lifecycle events from app/api/webhook/clerk/route.ts (account_created, logged_in).
  • Error-handling standards: standards/security-model, standards/auth-model.
  • Observability: operations/observability.
  • Testing: operations/testing-strategy — Vitest in apps/brisket/src/server/api/tests/.