Skip to content

Plan Undici 8 migration after dropping Node 20 support #232

@GrahamCampbell

Description

@GrahamCampbell

We currently depend on undici and use it directly for fetch dispatchers, while most request execution still uses the Node global fetch.

Current direct usage:

  • lib/utils/serverless-utils/download.js: imports Agent and passes it as a fetch dispatcher for rejectUnauthorized: false downloads.
  • lib/plugins/plugin/lib/utils.js: imports ProxyAgent and passes it as a fetch dispatcher for plugin registry requests through proxy env vars.
  • Additional direct fetch call sites use the global implementation: rollback-function.js, download-template-from-repo.js, standalone.js, and utils/standalone.js.

undici@8.2.0 currently declares engines: { node: ">=22.19.0" }, so it is not compatible with the current project engine range of ^20.19.0 || ^22.13.0 || >=24.

Undici 8 also changes lower-level dispatcher internals. To avoid mixing Undici 8 dispatchers with Node built-in global fetch, the migration should use undici.fetch consistently for direct fetch usage.

Proposed Scope

  • Raise the package Node engine floor to at least >=22.19.0 after Node 20 support is intentionally dropped.
  • Upgrade undici to ^8.2.0 or the latest compatible 8.x release at the time of the change.
  • Import fetch from undici at all direct fetch call sites in lib.
  • In serverless-utils/download.js, import Headers from undici as well so fetch, Headers, and Agent come from the same implementation.
  • Keep AWS SDK HTTP handling out of scope.
  • Keep generated/runtime custom resource https usage out of scope.

Direct Fetch Call Sites To Review

  • lib/utils/serverless-utils/download.js
  • lib/plugins/plugin/lib/utils.js
  • lib/plugins/aws/rollback-function.js
  • lib/utils/download-template-from-repo.js
  • lib/plugins/standalone.js
  • lib/utils/standalone.js

Test Updates

  • Replace tests that monkeypatch globalThis.fetch with proxyquire stubs for undici.fetch, or use Undici MockAgent where integration-style behavior is needed.
  • Preserve coverage for manual redirects and redirect body cancellation in serverless-utils/download.
  • Preserve coverage that proxy-backed plugin registry fetches pass a dispatcher.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions