Node's global fetch (powered by undici) wraps low-level failures in a terse TypeError: fetch failed. The real reason is in the cause chain - usually a transient DNS, connection, or TLS problem.
What this error means
A request made with the built-in fetch rejects with TypeError: fetch failed. The same call works locally and often passes when the job is retried, pointing at a flaky network rather than a code bug.
Confirm DNS/proxy settings and that any local service the test calls is started before the request runs.
Check HTTP(S)_PROXY/NO_PROXY env in the runner.
Wait for local servers to be ready before issuing requests.
Verify the host resolves and is allowlisted from the runner.
How to prevent it
Always read err.cause to classify the underlying failure.
Add bounded retries around outbound calls for genuinely transient classes.
Wait for dependent services to be ready before making requests.
Frequently asked questions
What causes ""TypeError: fetch failed""?
A dropped connection, slow DNS, or a momentary registry/API blip surfaces as fetch failed. These are intermittent and pass on retry.
How do I fix "TypeError: fetch failed"?
Log err.cause to see the underlying code, then wrap the request in a bounded retry for transient classes.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.