Real fixes from seven live sites. No pitch.Log in / My reports
Idea to Traffic Pressure Test

A deploy deleted files you did not touch

A Cloudflare Pages deploy replaces the entire site with the folder you deploy. It is not a merge. Deploy one page from a folder missing your icons, ads.txt or verification files and they disappear from production. Always deploy from a full checkout, and diff the file list before each deploy.

One deploy that wiped files it never touched

We pushed one updated page to a Cloudflare Pages project and lost the rest of the site. The icons came back 404, ads.txt was gone, and a search engine verification file placed weeks earlier had vanished. Nothing had been deleted on purpose. A Pages deploy replaces the entire site, so the folder we deployed became the complete contents of the site and everything absent from it stopped existing.

The files we lost were the predictable ones: binaries that were never committed, ads.txt added by hand during an ad network setup, and verification and IndexNow key files whose values a third party is holding. Rolling back to the last good deployment restored the full previous file set, including the binaries that were not in the repository.

You deployed one updated page. Now your icons are 404, your ads.txt is gone, and a verification file you set up weeks ago has vanished.

Nothing deleted them on purpose. A Pages deploy replaces the entire site. It is not a merge, not a sync, and not incremental. Whatever is in the folder you deploy becomes the complete contents of the site, and anything absent from that folder ceases to exist.

Why this catches people

The mental model most of us bring from FTP and from rsync is additive: push what changed, leave the rest. Deploy commands that take a directory argument look like they work the same way. They do not. The directory is the new site, in full.

npx wrangler pages deploy . --project-name=my-site

Run that from a folder holding one HTML file, and your site is now one HTML file.

What tends to disappear

The losses are predictable, because they are the files nobody keeps in their working folder:

  • Favicons, touch icons and Open Graph images, which are binary and often were never committed
  • ads.txt, added directly during an ad network setup and never written down
  • Search engine verification files, whose removal quietly un-verifies the property
  • IndexNow key files, which must keep matching what was registered with the search engine
  • .gitignore, if you built the folder with tar --exclude=.git, which drops it too

How to not do this

Diff before you deploy. The whole safeguard is one command:

diff -rq ./deploy-folder ./repo-checkout

Anything listed as "Only in repo-checkout" is about to be deleted from production. Decide that on purpose or not at all.

Then verify after, against the live site rather than your assumptions. Status codes are enough, and the list should include every file that is not linked from a page, because those are the ones no visitor will ever report as broken:

for f in ads.txt robots.txt sitemap.xml favicon.ico og-image.png; do
  echo "$f -> $(curl -s -o /dev/null -w '%{http_code}' https://yourdomain.com/$f)"
done

Recovering, in the right order

If it has already happened, do the rollback first and the investigation second. Every minute the site is missing files is a minute an ad crawler, a search crawler, or a verification check can read the broken version and record it.

Cloudflare keeps every previous deployment. Open the project, find the last deployment you trust, and roll back. That restores the complete file set from that build immediately, including the binaries that are not in your repo.

Then, before deploying anything again, reconstruct the folder properly. The failure mode here is deploying a second time to fix the first, from the same incomplete folder, which undoes the rollback and wastes it. Get the folder right, diff it against the rolled-back deployment, and only then push.

If the rollback list does not go back far enough, the missing files have to come from somewhere else. This is the moment people discover that their only copy of a favicon was on the live site.

Know which of your files are unrecoverable

Not everything on a site is equally replaceable, and it is worth sorting them once.

Regenerable. HTML, CSS, JavaScript, anything built from source. If it is in version control you can rebuild the site from scratch.

Replaceable with effort. Images, icons, Open Graph cards. You can remake them, and the remake will not match, which matters more than it sounds when the old one is cached in social previews and search results.

Genuinely unrecoverable. Files whose contents were issued by a third party and must match a value that party is holding. Search engine verification files. IndexNow key files, which have to match the key registered with the search engine, so a regenerated key is a new key and the old submissions stop being trusted. Any file a payment or ad platform told you to place at a specific path.

That third category is the one to protect, and the protection is trivial: commit them. They are a few bytes each, they never change, and they are exactly the files that never end up in a working folder because nobody thinks of them as part of the site.

Deploy from a checkout, not from a working folder

The structural fix behind all of this is that the folder you deploy should be produced by a repeatable process rather than assembled by hand.

Version control holds the source. A build or a copy step produces the deploy folder. The deploy folder is disposable, and if it is missing something, the fix is in the build step rather than in the folder. That way a partial deploy is impossible, because the folder is never partial.

The anti-pattern to name specifically: rebuilding a site by downloading the live version. It feels efficient and it makes production the source of truth, which means a single bad deploy destroys the only copy. Sync in the other direction. Deploy to production, verify, then mirror production into the repository if it has drifted, and commit that.

A few practical notes if you are scripting this. rsync is not installed in every container, and a short Python copy is a reliable substitute. tar --exclude=.git also drops .gitignore, which then goes missing from the folder and eventually from the repository. And a copy that silently skips dotfiles will skip exactly the verification files you were most worried about.

Make the diff a habit, not a decision

One command that you have to remember to run is a command you will eventually not run.

Wrap it. A four-line script that diffs, prints anything about to be deleted, and asks for confirmation costs nothing and turns the check from a discipline into a default:

diff -rq ./deploy ./repo | grep '^Only in ./repo' && {
      echo "Files above will be DELETED from production."
      read -p "Continue? [y/N] " a; [ "$a" = y ] || exit 1
    }
    npx wrangler pages deploy ./deploy --project-name=my-site

Preview deployments are free, use them

Pages builds a preview URL for any branch that is not production. Deploying a questionable change to a preview branch first costs nothing, gives you a real URL to check, and cannot damage the live site.

It is particularly worth doing when the change involves the shape of the folder rather than the contents of a file, which is precisely when this failure occurs. A preview deploy of a folder missing your icons shows you a preview missing icons, and you find out for free.

Recovering files a deploy already removed

A rollback and a pre-deploy diff protect the file set, and neither of them recovers a file whose only copy was the live site. If the deployment list does not reach back far enough, images and icons have to be remade and the remake will not match what is cached in social previews and search results, while verification and IndexNow key files cannot be regenerated at all, because a new key is a new key and the old submissions stop being trusted. The diff also says nothing about what happened while the files were missing: a property that un-verified during that window stays un-verified until you fix it, and any crawler or ad network check that read the broken version already recorded it.

Questions about Wrangler deploys replacing files

Does wrangler pages deploy delete files that are not in my folder?

Yes. The deploy is not a merge, a sync, or an incremental update. The directory you pass becomes the complete contents of the site, so anything absent from it ceases to exist.

Can I get my files back after a bad Pages deploy?

Cloudflare keeps previous deployments. Open the project, find the last deployment you trust, and roll back, which restores the complete file set from that build immediately, including binaries that are not in your repository.

Why did <code>ads.txt</code> disappear when I only changed one page?

ads.txt is usually added directly during an ad network setup and never written down, so it lives on production and not in your working folder. A deploy from that folder removes it along with anything else the folder does not contain.

How do I check a deploy before it goes live?

Run diff -rq ./deploy-folder ./repo-checkout and read anything listed as "Only in repo-checkout" as about to be deleted from production. For a change to the shape of the folder rather than the contents of a file, deploy to a preview branch first, which costs nothing and cannot damage the live site.

Does <code>tar --exclude=.git</code> cause any other losses?

It also drops .gitignore, which then goes missing from the folder and eventually from the repository. A copy step that silently skips dotfiles will skip exactly the verification files you were most worried about.

Which files should I commit even though they feel separate from the build?

The ones issued by a third party that must match a value that party holds: search engine verification files, IndexNow key files, and any file a payment or ad platform told you to place at a specific path. They are a few bytes each and they never change.