When every "Save" button in your dashboard fails at once
- live fix on app.rankrentai.com
- production worker logs
- verified DB row
What you're doing and why
Your dashboard is the control room for the whole business — tracking keywords, ticking checklist steps, approving pages. If pressing "Save" anywhere in it pops a red "Something went wrong" and nothing actually saves, you are flying blind. This lesson is about how we chased that bug, why it hid from three rounds of testing, and the one log line that exposed it.
The exact steps
- Reproduce it yourself first. Press the button that fails, once, while watching. Half of bug fixing is seeing the exact failure with your own eyes.
- Check the data layer before blaming the app. We opened the database and confirmed the table, columns and rules were all correct — the failed saves never even arrived. That tells you the problem is between the browser and the database, not in the data.
- Get the REAL error, not the generic one. Dashboards deliberately hide server errors
from users (a security feature — the message you see is a random "digest", not the
actual error). The actual error only exists in the server's own logs. We asked our
hosting tool for them (
shiply logs brisk-finch-rfpw) and the answer was one line: the server was refusing every save because the request arrived through our custom domain but carried the internal machine name — it looked exactly like a forgery attack, so it was blocked by design. - Tell the app which domain names are legitimate. One small settings change (a list of "allowed origins": our public domain plus the internal hostnames) and every form in the dashboard started saving again.
- Prove the fix where the user actually works. We didn't trust a local test — we drove the real live dashboard in a real logged-in browser, saved a keyword named "agent verification test", and confirmed it appeared in the live database. Then we cleaned up after ourselves.
What it looked like for us
- Before: every admin form save → instant red toast "Something went wrong", server
answered
500with an opaque error digest (...E80), zero rows reaching the database. - The smoking gun, from the production worker logs:
x-forwarded-host header ... does not match origin header ... from a forwarded Server Actions request. Aborting the action. - After: the same button click → keyword row visible in the on-screen table AND in the production database seconds later. Total cost of the fix: one config file and a redeploy. While in there we also shipped a security update of the app framework (Next.js 16.2.10 → 16.2.12) and restored the two missing portfolio thumbnails (the pictures existed on disk but had never been uploaded).
Gotchas
- The same symptom had TWO independent causes. Locally the failure was a genuine framework bug (fixed by the security update); in production it was the domain/proxy mismatch. Fixing one and declaring victory would have left the bug alive for the user. Always verify in the real production environment, not just locally.
- The error you see is not the error you have. A "digest" code in a toast is a lookup key, not a message. Find the server-side log before changing any code — guessing at a hidden error burns hours.
- Your infrastructure can impersonate an attacker. Putting an app behind a custom domain or reverse proxy changes the "return address" on requests. Any framework with forgery protection will then block its own legitimate traffic until you whitelist your public domain.
- HTTP 200 and "file exists" don't prove a page works. The dashboard was "up" the whole time — every page loaded fine. Only clicking the buttons revealed the failure. Test the actions, not just the pages.
- Untracked files don't deploy themselves. The two missing portfolio thumbnails had been generated days earlier but sat un-committed in a working folder; every deploy silently skipped them. If a fix isn't committed, it isn't shipped.