07. Launch Checks and Common Errors
This chapter is for the final check before you call the system live, plus the most common deployment mistakes people hit on their first pass.
1. Launch checklist
Section titled “1. Launch checklist”Before you call the deployment done, verify the basics one more time.
Frontend access
Section titled “Frontend access”Check:
- the public site opens normally
- the admin opens normally
- the correct domains are being used
Admin access
Section titled “Admin access”Check:
- login works
- the admin can read real project data
- obvious configuration pages are usable
Core user flow
Section titled “Core user flow”Check:
- signup or login works
- critical pages are not empty
- the product can read the current
app_keydata correctly
Optional modules
Section titled “Optional modules”If you enabled them, also check:
- payment flow
- AI flow
- blog flow
- notifications
- check-in
2. Production debugging: Cloudflare Observability (error logs)
Section titled “2. Production debugging: Cloudflare Observability (error logs)”When something fails in production and you cannot reproduce it locally, use the Cloudflare dashboard to inspect live Worker / Pages telemetry and errors.
Navigation (example: auth Worker):
- Open the Cloudflare Dashboard
- Go to Compute → Workers & Pages
- Open the target project, e.g.
zship-node1-auth(use the exactnamefrom your wrangler config) - Open Observability
From Observability you can inspect requests, error stacks, console output, and related signals—useful for 5xx responses, uncaught exceptions, and upstream failures.
If logs are empty: Observability may not be enabled for that Worker or Pages project yet. In the same project’s settings, find the Observability controls and enable them, then reproduce the issue and refresh the view.
Tip: Repeat for each service you need to debug (for example
zship-node3-pay,zship-node10-ai, or your frontend Pages app)—each has its own Observability scope.
3. CDN / R2 issues: keep CDN_PUBLIC_URL aligned with the R2 public hostname
Section titled “3. CDN / R2 issues: keep CDN_PUBLIC_URL aligned with the R2 public hostname”When uploads fail, files 404, or node6-cdn-service errors, first verify that the public base URL in the Worker matches the R2 custom domain you serve files from. If they diverge, the Worker may write objects correctly but return URLs that do not resolve to the same public entrypoint.
Two tracks below: §3.1–§3.4 are entirely in the Cloudflare Dashboard (first-time domain setup and UI walkthrough). §3.5 uses the ZShip Dev Console — for day-to-day CDN_PUBLIC_URL updates, prefer Dev Console so you skip hunting through Workers & Pages → Variables and Secrets in the CF UI.
Path A — Cloudflare Dashboard (§3.1–§3.4)
Section titled “Path A — Cloudflare Dashboard (§3.1–§3.4)”Everything in this path happens in the Cloudflare Dashboard: R2 custom domains, Worker env vars, and optional Worker hostnames.
3.1 Set CDN_PUBLIC_URL in the Dashboard
Section titled “3.1 Set CDN_PUBLIC_URL in the Dashboard”- Compute → Workers & Pages → open
zship-node6-cdn - Settings → Variables and Secrets
- Set
CDN_PUBLIC_URLto your R2 public base URL (includehttps://, usually no trailing path)
3.2 Where the R2 public URL comes from
Section titled “3.2 Where the R2 public URL comes from”- Storage & databases → R2 object storage
- Under Overview, open your bucket (example name
zship-cdn— use the bucket you actually created) - Settings → Custom Domains
Bind the hostname that should serve files publicly (for examplehttps://cdn.example.com).
3.3 The two values must match
Section titled “3.3 The two values must match”| Location | Setting | What to put |
|---|---|---|
Worker zship-node6-cdn | CDN_PUBLIC_URL | Same root URL as the R2 custom domain (https://your-cdn-hostname) |
| R2 bucket | Custom Domains | The same hostname you configured above |
They must stay in sync so zship-node6-cdn generates URLs that point at the same objects users can fetch.
3.4 Exposing the CDN Worker on the public internet
Section titled “3.4 Exposing the CDN Worker on the public internet”If you also need the upload Worker itself on its own hostname (not only the R2 public domain), bind a domain / route to zship-node6-cdn under Workers & Pages → that Worker → Settings → Domains & Routes (or Custom Domains). Many setups only need §3.3—R2 custom domain + matching CDN_PUBLIC_URL.
Path B — ZShip Dev Console (§3.5) — preferred for routine changes
Section titled “Path B — ZShip Dev Console (§3.5) — preferred for routine changes”Why Dev Console matters: You can edit CDN_PUBLIC_URL, push straight to the live Worker, and follow with a redeploy in one workflow — without bouncing between Cloudflare menus (Workers & Pages → … → Variables and Secrets). It matches how you already manage secrets and deploys from this repo, which cuts context switching when debugging or shipping.
3.5 Push CDN_PUBLIC_URL from Dev Console and redeploy
Section titled “3.5 Push CDN_PUBLIC_URL from Dev Console and redeploy”- Open Dev Console → Shipping → Deploy (labels may match your local build)
- Environment variables → Worker environment
- Select cdn backend (maps to
zship-node6-cdn) - Edit
CDN_PUBLIC_URL, then Push to zship-node6-cdn (or equivalent) to write vars to the live Worker - Redeploy
zship-node6-cdnso the change takes effect
Note: If the R2 Custom Domain has never been created, do §3.2 in the Dashboard once. After that, routine URL-only updates can stay in §3.5.
4. Common error 1: service binding target not found
Section titled “4. Common error 1: service binding target not found”Typical causes
Section titled “Typical causes”- you renamed a Worker (does not match
namein wrangler.jsonc) - you deployed using the wrong Cloudflare account
- deploy order: a Worker with service bindings depends on a target that has not been deployed yet
What to do
Section titled “What to do”- keep Worker names consistent with wrangler.jsonc
- run
wrangler whoamiand verify you are in the intended account - deploy in dependency order (Workers without bindings first)
5. Common error 2: D1, KV, or R2 resources cannot be found
Section titled “5. Common error 2: D1, KV, or R2 resources cannot be found”Typical causes
Section titled “Typical causes”- resources were never created
- config files still contain placeholders
- resource IDs were copied incorrectly
What to do
Section titled “What to do”- verify the resources exist in Cloudflare
- compare config values carefully
- replace all placeholder values before redeploying
6. Common error 3: admin login returns 401
Section titled “6. Common error 3: admin login returns 401”Typical causes
Section titled “Typical causes”- auth secrets are wrong
- frontend points at the wrong auth URL
- the domain configuration is inconsistent
What to do
Section titled “What to do”- verify auth secrets again
- verify auth endpoints again
- confirm the deployed frontend is using the latest environment values
7. Common error 4: pages open, but all data is empty
Section titled “7. Common error 4: pages open, but all data is empty”Typical causes
Section titled “Typical causes”- the frontend points at the wrong backend
- the wrong
app_keyis in use - the admin and frontend are not reading the same dataset
What to do
Section titled “What to do”- verify frontend environment variables
- verify the real
app_key - confirm the backend services and admin data belong to the same project
8. Common error 5: the payment page opens, but payment does not work
Section titled “8. Common error 5: the payment page opens, but payment does not work”Typical causes
Section titled “Typical causes”- provider keys are missing
- webhook config is incomplete
- pricing or product data is not configured correctly
What to do
Section titled “What to do”- verify payment provider secrets
- verify webhook configuration
- verify product and pricing data in the admin
9. Common error 6: the AI page opens, but sending a message fails
Section titled “9. Common error 6: the AI page opens, but sending a message fails”Typical causes
Section titled “Typical causes”- provider keys are missing
- model config is incomplete
- gateway or upstream settings are wrong
What to do
Section titled “What to do”- verify AI provider keys
- verify model mapping
- verify the deployed AI service is reading the intended environment values
10. Common error 7: Pages deploy says Invalid binding SESSION
Section titled “10. Common error 7: Pages deploy says Invalid binding SESSION”This usually means the expected binding exists in code or config, but is not properly created or attached in the target environment.
What to do
Section titled “What to do”- verify the Cloudflare binding exists
- verify the Pages environment is using the right binding name
- redeploy after fixing the binding configuration
11. Email does not send or lands in spam
Section titled “11. Email does not send or lands in spam”Typical causes
Section titled “Typical causes”- DNS for your sending domain is incomplete (SPF, DKIM, DMARC — follow your mail provider’s checklist)
- Wrong SMTP / provider secrets or sender settings for
node4-notify-service(admin or Worker env) - Broken templates or routing so requests never reach the notify Worker
What to do
Section titled “What to do”- Follow Email for DNS and channel configuration
- Check Observability on
zship-node4-notify(or your renamed notify Worker) for errors - Send a test message from the admin and review provider delivery logs if available
12. Payment or third-party webhooks never arrive / status stuck
Section titled “12. Payment or third-party webhooks never arrive / status stuck”Typical causes
Section titled “Typical causes”- Callback URL is not a public hostname (still on
*.workers.devor internal URL) — same as Domains & environment:node3-payneeds a real domain - Stripe / Creem webhook URL or signing secret does not match production (wrong environment, mixed staging/prod)
- Provider retries expired — you may need to reconcile manually in admin
What to do
Section titled “What to do”- Confirm the
zship-node3-paypublic URL matches the webhook endpoint in the payment dashboard (includinghttps://) - Use Observability on
zship-node3-payto see whether callbacks hit the Worker and whether they return 4xx/5xx - Re-read Payment for price, channel, and project bindings
If the browser shows CORS errors, the frontend origin often does not match what the API allows — align SITE_URL, project domains, and gateway settings, then retry.
13. One final recommendation
Section titled “13. One final recommendation”If something breaks, do not panic and do not rewrite half the setup at once.
Use the simplest debugging loop:
- identify one likely cause
- change one thing
- redeploy or retry
- observe the result
That is the fastest way to converge on a stable production setup.