Uh oh!
There was an error while loading. Please reload this page.
fix(frontend): fail build when BACKEND_URL unset; document staging footgun - #281
Conversation
…otgun
A staging frontend build without a build-time BACKEND_URL falls back to
http://localhost:5000 in the /api rewrite destination. Next's path-to-regexp
then misreads the :5000 port as a route param ('Expected "5000" to be a
string'), so every proxied /api/* call 500s at the worker while the backend
itself is healthy. wrangler.toml [vars] is runtime-only and does not cover the
build-time rewrite.
Throw at build time when NODE_ENV=production and BACKEND_URL is unset so a
broken worker can never ship silently again, and document the build-time vars
(and the SESSION_SECRET parity requirement) in the staging checklist.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Warning Review limit reached
More reviews will be available in 55 minutes and 29 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a production-only guard in ChangesBACKEND_URL Guard and Staging Secrets Docs
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ 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 |
Deploying with |
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs | frontend-staging | be33f4b | Commit Preview URL Branch Preview URL | Jun 28 2026, 04:08 AM |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/staging/setup-checklist.md`:
- Line 43: The setup checklist has a mismatch: it says BACKEND_URL must be
provided at build time, but the “What secret goes where” table still lists
BACKEND_URL under wrangler.toml runtime vars. Update that table to move
BACKEND_URL out of the runtime-vars grouping and clearly mark it as a build-time
variable alongside NEXT_PUBLIC_API_URL, while keeping COOKIE_DOMAIN in the
runtime worker vars section, so the guidance stays consistent with
next.config.ts behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 640b39e7-097e-4ecd-89d8-5de2b36e344f
📒 Files selected for processing (2)
docs/staging/setup-checklist.mdfrontend/next.config.ts
| ### Step 4 — Cloudflare Workers (the frontend service) | ||
| - [ ] The `[env.staging]` block in `frontend/wrangler.toml` is already in the repo (Phase 4). Deploy: `cd frontend && npm run cf:deploy:staging` → publishes a `frontend-staging` worker. | ||
| - [ ] **Set the build-time env vars** `BACKEND_URL` and `NEXT_PUBLIC_API_URL` (both `https://api.staging.saplinglearn.com`) for the staging build. These are read by `next.config.ts`/client bundles at **build time** — `wrangler.toml [env.staging.vars]` is runtime-only and does NOT cover them. If you deploy via Cloudflare Workers Builds, add them as **Build variables** on the staging build; if you deploy locally, export them before `npm run cf:deploy:staging` (also export `NEXT_PUBLIC_LOCAL_MODE=false` so a stray local `.env.local` can't flip staging into mock mode). Miss `BACKEND_URL` and the `/api` rewrite bakes `http://localhost:5000` → every dashboard API call 500s (`next.config.ts` now fails the build loudly if it is unset). |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Split BACKEND_URL out from the runtime-vars table entry.
Step 4 now correctly says BACKEND_URL must be present at build time, but the later “What secret goes where” table still groups BACKEND_URL with COOKIE_DOMAIN as a Cloudflare worker wrangler.toml var. That contradiction can send operators back to the same broken localhost rewrite path this PR is fixing.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/staging/setup-checklist.md` at line 43, The setup checklist has a
mismatch: it says BACKEND_URL must be provided at build time, but the “What
secret goes where” table still lists BACKEND_URL under wrangler.toml runtime
vars. Update that table to move BACKEND_URL out of the runtime-vars grouping and
clearly mark it as a build-time variable alongside NEXT_PUBLIC_API_URL, while
keeping COOKIE_DOMAIN in the runtime worker vars section, so the guidance stays
consistent with next.config.ts behavior.
A stray leading/trailing space in the Workers Builds BACKEND_URL variable makes the /api rewrite destination start with a space, which Next rejects at build time as 'Invalid rewrite found'. Trim the value so the build tolerates whitespace, and validate it is an absolute http(s) origin with a clear error that points at the variable instead of Next's cryptic message. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
What & why
Staging's dashboard was down: every proxied
/api/*call returned500. Root cause was isolated to the frontend Cloudflare worker, not the backend or DB:staging.saplinglearn.com/api/users→500 text/plain "Internal Server Error"(worker)api.staging.saplinglearn.com/api/users→401 application/json(backend healthy)The
frontend-stagingworker had been built with no build-timeBACKEND_URL, so the/api/:path*rewrite destination fell back tohttp://localhost:5000. Next's path-to-regexp then misreads the:5000port as a route param (TypeError: Expected "5000" to be a string), 500-ing every proxied call at runtime.wrangler.toml [vars]is runtime-only and does not cover the build-time rewrite.This PR
next.config.ts: throw at build time whenNODE_ENV=productionandBACKEND_URLis unset, so a broken worker can never ship silently again — the build fails loudly instead.docs/staging/setup-checklist.md: document the build-time env vars (BACKEND_URL/NEXT_PUBLIC_API_URL/NEXT_PUBLIC_LOCAL_MODE) and theSESSION_SECRETparity requirement.Operational note (do before/at merge)
Because this guard now fails the build without
BACKEND_URL, the Build variableBACKEND_URLmust be set on the Workers Builds config for both staging and prod, or the first build after merge fails:https://api.staging.saplinglearn.com(already set)https://api.saplinglearn.com(verify)The live staging worker was already hotfixed via a one-off local deploy with
BACKEND_URLset (verified: proxy500 → 401); this PR makes the fix durable in the pipeline.🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Documentation