fix(api): RL_PUBLIC binding + safety-net boundaries + dep upgrades#16
fix(api): RL_PUBLIC binding + safety-net boundaries + dep upgrades#16nathanialhenniges merged 4 commits intomainfrom
Conversation
trackView and trackClick mutations 500'd with `Cannot read properties of undefined (reading 'limit')`. The Hono cloudflareRateLimiter middleware on /trpc/public.trackView* and /trpc/public.trackClick* reads c.env.RL_PUBLIC and immediately calls .limit() on it, but RL_PUBLIC was never declared in alchemy.run.ts and never bound to the server worker. apps/server/wrangler.jsonc lists RL_PUBLIC (ns 1004) but Alchemy is the dev-time source of truth -- the wrangler.jsonc drift is what made the binding look wired on paper. Other public routes work because they have no rate limiter (getPage) or use a binding that does exist (submitContact -> RL_AUTH). Fix: declare rlPublic alongside rlAuth/rlStrict/rlUpload (matching the wrangler.jsonc namespace 1004 + 60 req/60s) and add it to the server worker's bindings map. apps/server/src/index.ts already declares RL_PUBLIC: RateLimit in its Bindings type, so no code-side change is needed. Restart bun dev after pulling so Alchemy registers the new binding. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Safety-net pass on apps/web for Next.js 16 / React 19 conventions:
apps/web/src/app/error.tsx Root error boundary (client). Catches
uncaught errors anywhere under /, shows
reset button + error digest.
apps/web/src/app/not-found.tsx Branded 404 page (server component).
apps/web/src/app/loading.tsx Streaming UI for the root layout's async
fetchSettings() — matches the existing
spinner pattern in app/page.tsx.
apps/web/src/app/admin/error.tsx Admin-scoped error boundary (client).
Keeps admin chrome visible.
apps/web/src/app/admin/loading.tsx Skeleton matching the admin dashboard
layout. Softens the wait while the 12
parallel tRPC queries on /admin resolve.
Pin alignment (zero-risk, no version bumps):
next 16.1.6 -> 16.2.0 (apps/docs aligns with apps/web)
typescript ^5 -> ^5.9.3 (web, server, api, auth, db, ui,
email, env, infra, validators)
@types/node ^25 -> ^25.5.0 (apps/web aligns with rest)
bun.lock regenerated. apps/docs/next-env.d.ts regenerated by `next typegen`.
Verification:
bun run check-types green (server, docs)
bunx tsc --noEmit green (apps/web)
Out of scope this round (deferred): admin layout RSC refactor, Server
Actions migration, Next 16 'use cache' for the public page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
56 dependency bumps inside existing major versions. No major bumps
this round (typescript 5.9.3->6.0.2, alchemy 0.89->0.91, jsdom 28->29
deferred — pre-1.0 alchemy minor counts as breaking).
Notable bumps:
next: 16.2.0 (already current)
react / react-dom: 19.2.4 -> 19.2.5 (patch)
@trpc/* (client/server/tanstack-react-query):
11.12.0 -> 11.16.0 (minor)
better-auth: 1.5.5 -> 1.6.3 (minor)
hono: 4.12.7 -> 4.12.14 (patch)
drizzle-orm: 0.45.1 -> 0.45.2 (patch)
drizzle-kit: 0.31.9 -> 0.31.10 (patch)
wrangler: 4.72.0 -> 4.83.0 (minor)
@cloudflare/workers-types:
4.20260403.1 -> 4.20260415.1 (minor)
@tanstack/react-query: 5.90.21 -> 5.99.0 (minor)
@tanstack/react-form: 1.28.5 -> 1.29.0 (minor)
@opennextjs/cloudflare: 1.17.1 -> 1.19.1 (minor)
@base-ui/react: 1.3.0 -> 1.4.0 (minor)
@headlessui/react: 2.2.9 -> 2.2.10 (patch)
recharts: 3.8.0 -> 3.8.1 (patch)
shadcn: 4.0.5 -> 4.2.0 (minor)
@react-email/components:1.0.9 -> 1.0.12 (patch)
@react-email/render: 2.0.4 -> 2.0.6 (patch)
postcss: 8.5.8 -> 8.5.9 (patch)
dotenv: 17.3.1 -> 17.4.2 (patch)
turbo: 2.9.3 -> 2.9.6 (patch)
vitest: 4.1.2 -> 4.1.4 (patch)
tsdown: 0.21.2 -> 0.21.8 (patch)
@t3-oss/env-nextjs: 0.13.10 -> 0.13.11 (patch)
@types/node: 25.5.0 -> 25.6.0 (minor)
@linkden/ui peerDependencies tightened: react / react-dom ^19.0.0 ->
^19.2.5 to match the rest of the monorepo.
Verification:
bun install green (390 packages installed clean)
bun run check-types green (server, docs)
bunx tsc --noEmit green (apps/web)
bun run build green (web, docs, server) with placeholder env
Surfaced for follow-up (out of scope this round):
Next.js 16.2 deprecates the `middleware.ts` file convention in
favor of `proxy.ts` — `apps/web/src/middleware.ts` will need to be
renamed/migrated separately.
apps/web/next-env.d.ts regenerated by `next build`.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
# Conflicts: # bun.lock
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 50 minutes and 32 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (20)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Three bundled commits on
claude/epic-villani, plus a merge of latestmain.1.
fix(api): bind RL_PUBLIC rate limiter to server worker(6fe4452)POST /trpc/public.trackViewandtrackClickwere 500'ing withCannot read properties of undefined (reading 'limit').Root cause: the Hono
cloudflareRateLimitermiddleware mounted onthose two routes reads
c.env.RL_PUBLICand immediately calls.limit()on it — butRL_PUBLICwas never declared inpackages/infra/alchemy.run.ts. OnlyrlAuth,rlStrict, andrlUploadexisted. The wrangler.jsonc file hadRL_PUBLIC(ns 1004)but Alchemy is the dev-time source of truth, so the binding was
silently missing in dev and prod.
Fix: declare
rlPublic(ns 1004, 60 req / 60 s — matching thewrangler.jsonc spec) and add it to the server worker's
bindingsmap. The
Bindingstype inapps/server/src/index.tsalreadydeclared
RL_PUBLIC: RateLimit, so no other code change was needed.2.
chore(web): add error/loading/not-found boundaries + align package pins(8213d43)Safety-net pass on
apps/webfor Next.js 16 / React 19 conventions:apps/web/src/app/error.tsx— root error boundary (client) with reset buttonapps/web/src/app/not-found.tsx— branded 404 (server component)apps/web/src/app/loading.tsx— root streaming UI matching the existing spinner patternapps/web/src/app/admin/error.tsx— admin-scoped error boundary keeping admin chrome visibleapps/web/src/app/admin/loading.tsx— skeleton for the 12-parallel-tRPC-query dashboardPin alignment (zero-risk, no version bumps):
next16.1.6 -> 16.2.0(apps/docs aligned with apps/web)typescript^5 -> ^5.9.3(web, server, api, auth, db, ui, email, env, infra, validators)@types/node^25 -> ^25.5.0(apps/web aligned with rest)3.
chore(deps): patch + minor upgrades across workspaces(a8b2e3d)56 dependency bumps inside existing major versions. Highlights:
@trpc/*11.12.0 -> 11.16.0better-auth1.5.5 -> 1.6.3@tanstack/react-query5.90.21 -> 5.99.0@tanstack/react-form1.28.5 -> 1.29.0wrangler4.72.0 -> 4.83.0@cloudflare/workers-types4.20260403.1 -> 4.20260415.1@opennextjs/cloudflare1.17.1 -> 1.19.1@base-ui/react1.3.0 -> 1.4.0react / react-dom19.2.4 -> 19.2.5hono4.12.7 -> 4.12.14drizzle-orm0.45.1 -> 0.45.2dotenv17.3.1 -> 17.4.2shadcn4.0.5 -> 4.2.0recharts3.8.0 -> 3.8.1Skipped (out of scope this round): typescript 5.9.3 -> 6.0.2, alchemy 0.89 -> 0.91, jsdom 28 -> 29 (all major / pre-1.0 minor).
@linkden/uipeerDependenciestightened:react/react-dom^19.0.0 -> ^19.2.5to match the rest of the monorepo.4. Merge
origin/mainPulled
d322087 fix: Add Social Network modal with URL validation (#13)into the branch. The only conflict wasbun.lock, resolved by re-runningbun installagainst the merged package.jsons.Surfaced for follow-up (out of scope here)
middleware.tsfile convention is deprecated in favor ofproxy.ts.apps/web/src/middleware.tswill need to be renamed/migrated separately.apps/web/src/app/admin/layout.tsxis currently"use client", dragging the entire admin tree to the client. Deferred.'use cache'for the public page: Next 16 cache directive not yet exploited onapp/page.tsx. Deferred.Test plan
bun install— clean (390 packages installed)bun run check-types— green (server, docs)bunx tsc --noEmit(apps/web) — greenbun run build— green (web, docs, server) with placeholder env varsbun devso Alchemy registers the newRL_PUBLICbinding/, confirmPOST /trpc/public.trackView?batch=1returns 200 (was 500)POST /trpc/public.trackClick?batch=1returns 200trackView~70× in a minute, confirm 429 on overflow (proves the rate limiter is wired and active)error.tsxrenders (no white screen)/totally-bogusto confirmnot-found.tsxrenders/admin/loginand load/admin— confirm the newloading.tsxskeleton flashes briefly and all 12 tRPC queries return 200/admin/builderand confirm the dashboard worksbun run deploy— left for the maintainer to run after review🤖 Generated with Claude Code