We pushed a change, ran the deploy, watched it upload 958 files, and got:
✨ Success! Uploaded 958 files
Deployed my-project triggers
https://my-project.accountname.workers.dev
Current Version ID: 41b206cb-...
Then I checked the live site. The change was not there.
Not cached. Not stale. Simply not there. The deploy had succeeded perfectly, into a place
nobody looks.
Two things can own the same name
Cloudflare will happily let you have:
- a Pages project called
my-project, with your custom domain attached to it, and - a Worker called
my-project, serving static assets from awrangler.jsoncin your repo root.
Same name. Same account. Completely separate deploy targets. wrangler deploy publishes
to the Worker. The custom domain was attached to the Pages project. Both are real, both
were "working", and the success message was true. It just answered a question I had not
asked.
The repo had a wrangler.jsonc describing a Workers-assets setup, so every signal in the
codebase pointed at wrangler deploy. The actual production path was
wrangler pages deploy. Nothing in the repo said so.
How to tell which one serves your domain
Do not infer it from the config file. Ask the API:
npx wrangler pages project list
The output lists each project with its domains attached:
│ my-project │ my-project.pages.dev, mydomain.com │ ... │ 8 hours ago │
If your domain appears there, Pages owns it, and wrangler deploy is shouting into a
void.
The faster check when you suspect a deploy went nowhere: compare the hashed asset filename
your build produced against the one the live HTML references.
grep -o 'assets/index-[A-Za-z0-9_-]*\.js' dist/index.html
curl -s "https://mydomain.com/?cb=$RANDOM" | grep -o 'assets/index-[A-Za-z0-9_-]*\.js'
Two different hashes means the live site is serving a different build than the one on your
disk. That is a one-line answer to "is my deploy live", and it does not care what the
deploy log claimed.
Then Pages refused to deploy at all
Having worked out the right command, it failed:
wrangler pages deploy reads wrangler.jsonc, finds a Worker config with no
pages_build_output_dir, and refuses. Passing -c to point at a different config is
rejected too: "Pages does not support custom paths for the Wrangler configuration file."
So the workaround is genuinely to move the file out of the way:
mv wrangler.jsonc wrangler.worker.jsonc
npx wrangler pages deploy dist --project-name my-project --branch main --commit-dirty=true
mv wrangler.worker.jsonc wrangler.jsonc
Inelegant, and it works. Put it in a script so a failed deploy cannot leave the config
renamed.
The same trap, one level down
Later we set a secret:
cd worker-subdir
npx wrangler secret put MY_SECRET
Output: Creating the secret for the Worker "parent-project-name".
The subdirectory has its own wrangler.toml naming a different Worker. Wrangler resolved
to the parent directory's config anyway, and put the secret on the wrong Worker. It
reported success, because it did successfully do the wrong thing.
The tell was in wrangler secret list: one secret, when the Worker we wanted has ten. If
the secret list does not look like the Worker you have in mind, you are not talking to the
Worker you have in mind.
Fix: pass the config explicitly, every time.
npx wrangler secret put MY_SECRET -c wrangler.toml
npx wrangler deploy -c wrangler.toml
And when the deploy IS right but the page is old
After deploying to the correct target, the homepage still served the old bundle. This one
really was caching. New asset files were live and reachable, but the HTML referencing them
was not.
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE/purge_cache" \
-H "X-Auth-Email: $EMAIL" -H "X-Auth-Key: $KEY" \
-H "Content-Type: application/json" --data '{"purge_everything":true}'
Note that ?cb=$RANDOM busts a query-keyed cache but will not save you here, which is
what made it confusing: the asset URL returned 200 while the HTML kept pointing at the
previous hash.
What I take from it
- "Deployed successfully" answers "did the upload work", not "is it live for users." Those are different questions and only one of them matters.
- Verify deploys by comparing build output to what the domain actually serves. Hashed filenames make this trivial, so there is no excuse for guessing.
- When a CLI walks up the directory tree for config, always pass the config explicitly. Silent resolution to the wrong target is worse than an error.
- If a tool reports success and reality disagrees, suspect you asked a different question than the one you meant.
We hit all of these in one session working on CVBooster. The change
was fine the whole time. Everything else was wrong.
Top comments (0)