Skip to content

Fetch call causes exceptions when process.exit is called shortly after it #5680

Description

@art-alexeyenko

Bug Description

On Windows platforms, fetch will cause an exception (Assertion failed..) to be thrown on process.exit() call, if it's called shortly after a fetch() execution. This could affect fetch calls within CLI logic. Why it happens:

  1. Native fetch is undici. On a successful request undici returns the
    socket to a keep-alive pool (default keepAliveTimeout = 4s) instead of
    closing it. The fetch controller does not abort/close on success.
  2. The pooled socket keeps libuv handles alive (a TCP handle + a uv_async_t/timer).
  3. process.exit(0) tears the event loop down immediately. libuv closes handles;
    if undici's async handle is mid-teardown, libuv double-closes it and asserts.
    Windows' src/win/async.c is strict about this; POSIX usually isn't.

Reproduction

See: https://github.com/art-alexeyenko/node-fetch-handles

Steps to reproduce (if not using the script above):

  1. Use the reproduction repo on a Windows platform
  2. Run a mock server (npm run server)
  3. Run the repro (npm run repro). This will:
    a. Perform a fetch request to the local endpoint
    b. Execute process.exit(0)

Expected Behavior

No exception at the end.

Actual Behavior

Assertion failed: !(handle->flags & UV_HANDLE_CLOSING), file src\win\async.c, line 94 error occurs upon the process.exit call.

Logs & Screenshots

Sample log output

npm run repro

> undici-exit-crash-repro@1.0.0 repro
> node repro.mjs

Sent 2 requests
Assertion failed: !(handle->flags & UV_HANDLE_CLOSING), file src\win\async.c, line 94

Environment

  • OS: Windows
  • Node.js version: >=24
  • undici version: 7.29.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions