Vitest job fails on unhandled ECONNREFUSED from external script loaders while all tests pass
area:CI/CDarea:testing
## Symptom
The `test` job fails while the Vitest summary reports everything green:
```
Test Files 1107 passed (1107)
Tests 15169 passed | 8 skipped (15177)
```
The job still fails, because Vitest exits non-zero on **unhandled errors** rather than on assertion failures. The step that fails is `Run Vitest tests with coverage`.
## Cause
A worker dies on a connection refused to `localhost:3000`:
```
AggregateError:
code: 'ECONNREFUSED',
Error: connect ECONNREFUSED ::1:3000
Error: connect ECONNREFUSED 127.0.0.1:3000
```
Stack frames point at external-script loading, not at any test:
- `src/platform/telemetry/providers/cloud/GtmTelemetryProvider.ts`
- `src/utils/loadExternalScript.ts`
- `src/platform/surveys/useTypeformEmbed.ts`
Something schedules a real script load that outlives the test that triggered it, resolves against the dev-server origin, and rejects after teardown with nothing left to catch it.
## Observed
- https://github.com/Comfy-Org/ComfyUI_frontend/pull/14615 — 2026-08-04, run 30877619218. Reran the failed job, passed.
- https://github.com/Comfy-Org/ComfyUI_frontend/pull/14614 — 2026-08-05, run 31011079651, job 92323185082. Same signature.
Neither PR touches telemetry, surveys, or external script loading, so this is not caused by the changes under test.
## Why it is worth fixing rather than rerunning
It reads exactly like a real failure. The summary says every test passed, so the natural response is to assume the red is spurious and merge, which trains people to ignore a red `test` job. It also costs a full rerun each time.
## Suggested fix
Stub the external-script path in the unit-test setup so nothing reaches the network: mock `loadExternalScript` globally, or have `GtmTelemetryProvider` and `useTypeformEmbed` no-op when `import.meta.env.MODE === 'test'`. Failing that, ensure the promise is awaited or explicitly caught so a late rejection cannot become an unhandled error.
Worth checking whether `dangerouslyIgnoreUnhandledErrors` is the right escape hatch here, though suppressing it would hide genuine late rejections too.
2 条评论