Summary
Running eas deploy --prod corrupts the production custom domain binding when the immediately-preceding deploy was for a different environment (e.g. a preview deploy). The production *.expo.app URL keeps working, but the custom domain returns "No worker deployment was found matching the current domain" until either (a) eas deploy --prod is run a second time, or (b) the deploy and the production promotion are done as two separate steps.
Environment
- eas-cli 18.11.0
- expo 57.0.6, expo-router 57.0.6, expo-server 57.0.1
- EAS Hosting (server output: SSR data loaders +
+api routes + +middleware), production custom domain configured, bound to the production alias.
Repro
eas deploy --environment preview (a normal preview deploy)
eas deploy --prod --environment production
- Load the production custom domain → 502 "No worker deployment was found matching the current domain". The
<deployment>--<project>.expo.app prod URL and all preview URLs work fine.
- Run
eas deploy --prod --environment production again → custom domain recovers.
Works (workaround)
Splitting deploy from promotion never triggers it:
DID=$(eas deploy --environment production --json | jq -r '.identifier')
eas deploy:alias --prod --id "$DID"
Analysis
In eas-cli 18.11.0, deploy --prod and deploy:alias --prod both call assignWorkerDeploymentProductionAsync → the same AssignAlias(appId, deploymentId, aliasName: null) mutation. The two flows are API-identical; the only difference is that --prod performs the production alias assignment in-band, immediately after upload, whereas the split flow (and "deploy twice") promotes after a delay. This strongly suggests a server-side race between finalizing a freshly-uploaded deployment and re-pointing the production custom domain at it — the custom-domain reconciliation appears to run against a not-yet-serving deployment when the promotion happens too soon after upload.
Expected
eas deploy --prod should not leave the custom domain unroutable; either the promotion should wait until the deployment is servable, or the domain reconciliation should be resilient to the freshly-promoted deployment.
Summary
Running
eas deploy --prodcorrupts the production custom domain binding when the immediately-preceding deploy was for a different environment (e.g. a preview deploy). The production*.expo.appURL keeps working, but the custom domain returns "No worker deployment was found matching the current domain" until either (a)eas deploy --prodis run a second time, or (b) the deploy and the production promotion are done as two separate steps.Environment
+apiroutes ++middleware), production custom domain configured, bound to theproductionalias.Repro
eas deploy --environment preview(a normal preview deploy)eas deploy --prod --environment production<deployment>--<project>.expo.appprod URL and all preview URLs work fine.eas deploy --prod --environment productionagain → custom domain recovers.Works (workaround)
Splitting deploy from promotion never triggers it:
Analysis
In eas-cli 18.11.0,
deploy --prodanddeploy:alias --prodboth callassignWorkerDeploymentProductionAsync→ the sameAssignAlias(appId, deploymentId, aliasName: null)mutation. The two flows are API-identical; the only difference is that--prodperforms the production alias assignment in-band, immediately after upload, whereas the split flow (and "deploy twice") promotes after a delay. This strongly suggests a server-side race between finalizing a freshly-uploaded deployment and re-pointing the production custom domain at it — the custom-domain reconciliation appears to run against a not-yet-serving deployment when the promotion happens too soon after upload.Expected
eas deploy --prodshould not leave the custom domain unroutable; either the promotion should wait until the deployment is servable, or the domain reconciliation should be resilient to the freshly-promoted deployment.