cypress "cy.visit() failed trying to load" only in CI: baseUrl vs CI service hostname
Fixes Cypress 'cy.visit() failed trying to load' errors that happen only in CI because baseUrl points at a hostname the CI environment cannot resolve. Shows how to set baseUrl from the CI service hostname, wait for the app server before tests start, and smoke-check the URL in the pipeline. Use when cy.visit works locally but fails in CI. Not for app crashes on boot, pages that load but render wrong, or non-Cypress failures.
TL;DR
Locally your app answers on your machine's loopback address, but in CI it usually runs as a service under a different hostname that your hardcoded baseUrl cannot reach. Set baseUrl from an environment variable the CI job provides, add a wait step so Cypress never visits before the server is listening, and the failure disappears.
cypress "cy.visit() failed trying to load" only in CI: baseUrl vs CI service hostnameSteps
- Open your Cypress config and read the current
baseUrl. Then check what hostname the app actually binds to in CI (a service name, an internal host, or a dynamic port), from the CI job definition or the service logs. Expected: you can state both values and see they do not match. - Make
baseUrlconfigurable: read it from an environment variable with a local fallback, so CI injects its own hostname and local runs keep working unchanged. Expected: the config no longer hardcodes one hostname. - Set that variable in the CI job to the hostname the app service actually listens on. Expected: the variable is visible in the CI job environment.
- Add a wait step before Cypress starts (a
wait-onstyle check against the app URL) so the visit never races the server boot. Expected: Cypress starts only after the server answers. - Add a one-line smoke check in the pipeline that fetches the app URL before Cypress runs. Expected: the smoke check passes, then
cy.visit()loads the page.
Use this when
cy.visit()fails in CI but works on your machine- The app runs as a CI service with its own hostname or port
- The error is a connection failure, not a rendered error page
Not for this skill when
- The page loads but shows the wrong content (that is an app or data problem)
- The app itself crashes on boot in CI (fix the boot, not the URL)
- The failure happens locally too (the baseUrl is wrong everywhere)
Variant phrasings
- cypress cy.visit failed trying to load in CI pipeline
- cypress baseUrl not working in CI
- cypress cannot reach app server in CI
Why it happens
baseUrl is usually written once, on a developer machine where the app listens on the loopback address. CI runs the app as a separate service with its own hostname and often a different port, and it may still be booting when Cypress starts. The hardcoded local URL then points at nothing, and cy.visit() reports that it failed trying to load.
Edge cases
- If the CI hostname includes a dynamic port, have the server write its bound address to a file or env var the Cypress job can read, rather than guessing the port.
- HTTPS in CI with a self-signed cert fails the visit for a different reason; that needs the cert trusted, not a baseUrl change.
- When the app and Cypress run in the same container, the service hostname may not resolve there; use the container-local address for that layout.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_jK1bRxHfWJ30YLm3gSThTQ