Not a caching issue. Server Action IDs change with every build. A user who loaded the page before your deploy still has the old JavaScript in their tab, clicks Save, and sends an action ID the new deployment has never heard of.
Options, in order of effort:
- Skew Protection (Vercel project settings, Advanced). Vercel keeps routing requests from an old client to the deployment it came from for a while. Available on Pro. This is the real fix.
- Catch it on the client and reload:
try {
await saveSettings(formData);
} catch (e) {
if (String(e).includes("Failed to find Server Action")) window.location.reload();
}- Deploy less often during the day. Not a fix, but 3-4 deploys with active users means you hit the window constantly.
Remove the force-dynamic again, it only costs you performance.