Why editing your code changes nothing for deployed users
Apps Script web app deployments are versioned snapshots. When you click Deploy > New deployment (or the original Manage deployments dialog), Apps Script captures the state of your code at that moment and assigns it a version number. The public URL your users hit always resolves to that frozen version, not your current editor state.
The first time I hit this, I spent twenty minutes staring at a perfectly spelled doGet while the live URL kept returning the error. The live URL was still pointing at version 1, where doGet did not yet exist. I had never created a new deployment version after writing the function.
The fix is: Deploy > Manage deployments > edit the existing deployment > change version from the pinned number to 'New version' > click Deploy. The URL stays the same; the code it runs changes. If you want to test without touching the production URL, use the /dev endpoint (Deploy > Test deployments) — it always runs your current unsaved HEAD, no versioning involved.